@file-viewer/renderer-pdf 2.1.7 → 2.1.8

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.en.md CHANGED
@@ -39,6 +39,8 @@ const options = {
39
39
  }
40
40
  ```
41
41
 
42
+ When no explicit URL is provided, the renderer first probes `/vendor/pdf/pdf.worker.mjs` from the site root. If the host app did not run `file-viewer-copy-assets`, does not use `@file-viewer/vite-plugin`, or a local dev server falls back to HTML for that path, the renderer lazy-loads the packaged PDF.js worker handler as a compatibility fallback so preview does not fail with `Setting up fake worker failed`. For best performance, full cMap/WASM/standard-font support, or strict offline deployments, still copy viewer assets and point these URLs at real static files.
43
+
42
44
  ## Migration Note
43
45
 
44
46
  PDF rendering has moved out of `@file-viewer/core` into this package, and `pdfjs-dist` is now declared only by `@file-viewer/renderer-pdf`. Installing core or a standard component package no longer pulls PDF.js; explicitly assemble this renderer when PDF preview is needed, or use `@file-viewer/preset-all`.
package/README.md CHANGED
@@ -39,6 +39,8 @@ const options = {
39
39
  }
40
40
  ```
41
41
 
42
+ 默认未显式配置时,渲染器会先探测站点根路径的 `/vendor/pdf/pdf.worker.mjs`。如果客户项目没有执行 `file-viewer-copy-assets`、没有使用 `@file-viewer/vite-plugin`,或者本地临时服务器把该路径回退成 HTML,PDF renderer 会自动懒加载包内 PDF.js worker handler 作为兼容兜底,避免 `Setting up fake worker failed` 直接中断预览。需要最佳性能、完整 cMap/WASM/standard fonts 或严格离线部署时,仍建议复制 viewer assets 并配置真实静态地址。
43
+
42
44
  ## 迁移说明
43
45
 
44
46
  PDF 渲染已经从 `@file-viewer/core` 移入本包,`pdfjs-dist` 只由 `@file-viewer/renderer-pdf` 声明。只安装 core 或标准组件包时不会再拉取 PDF.js;需要 PDF 预览时请显式装配本 renderer,或使用 `@file-viewer/preset-all`。
package/dist/pdf.js CHANGED
@@ -10,6 +10,8 @@ const SCALE_STEP = 0.1;
10
10
  const FIT_HORIZONTAL_PADDING = 28;
11
11
  const PAGE_BORDER_WIDTH = 18;
12
12
  const PDF_EXPORT_MAX_PAGE_PIXELS = 8000000;
13
+ const PDF_WORKER_PROBE_TIMEOUT_MS = 1200;
14
+ let bundledPdfWorkerModulePromise = null;
13
15
  // PDF.js viewer CSS references image assets that are not shipped with the
14
16
  // on-demand renderer chunk, so keep the preview self-contained and 404-free.
15
17
  const normalizedPdfViewerStyle = pdfViewerStyle
@@ -86,6 +88,34 @@ const waitForPaint = (view) => new Promise(resolve => {
86
88
  }
87
89
  globalThis.setTimeout(resolve, 0);
88
90
  });
91
+ const isConfiguredUrl = (value) => {
92
+ return value !== undefined && value !== null && String(value).trim().length > 0;
93
+ };
94
+ const isJavaScriptLikeResponse = (response) => {
95
+ var _a;
96
+ const contentType = ((_a = response.headers.get('content-type')) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || '';
97
+ return !contentType ||
98
+ contentType.includes('javascript') ||
99
+ contentType.includes('ecmascript') ||
100
+ contentType.includes('application/octet-stream') ||
101
+ contentType.includes('text/plain');
102
+ };
103
+ const loadBundledPdfWorkerModule = async () => {
104
+ bundledPdfWorkerModulePromise !== null && bundledPdfWorkerModulePromise !== void 0 ? bundledPdfWorkerModulePromise : (bundledPdfWorkerModulePromise = import('pdfjs-dist/legacy/build/pdf.worker.mjs'));
105
+ return bundledPdfWorkerModulePromise;
106
+ };
107
+ const installBundledPdfFakeWorker = async () => {
108
+ var _a;
109
+ const workerGlobal = globalThis;
110
+ if ((_a = workerGlobal.pdfjsWorker) === null || _a === void 0 ? void 0 : _a.WorkerMessageHandler) {
111
+ return;
112
+ }
113
+ const workerModule = await loadBundledPdfWorkerModule();
114
+ workerGlobal.pdfjsWorker = {
115
+ ...workerGlobal.pdfjsWorker,
116
+ WorkerMessageHandler: workerModule.WorkerMessageHandler,
117
+ };
118
+ };
89
119
  const resolvePdfWorkerUrl = (options, documentUrl) => {
90
120
  return resolveFileViewerPdfAssetUrls(options, documentUrl).workerUrl;
91
121
  };
@@ -436,18 +466,76 @@ export default async function renderPdf(buffer, target, context) {
436
466
  targetWindow.requestAnimationFrame(writeLegacyCompatiblePageDimensions);
437
467
  });
438
468
  };
439
- const createPdfWorker = () => {
440
- if (!(targetWindow === null || targetWindow === void 0 ? void 0 : targetWindow.Worker)) {
441
- return null;
469
+ const canUseResolvedPdfWorkerUrl = async (workerUrl) => {
470
+ var _a, _b;
471
+ const fetcher = ((_a = targetWindow.fetch) === null || _a === void 0 ? void 0 : _a.bind(targetWindow)) || ((_b = globalThis.fetch) === null || _b === void 0 ? void 0 : _b.bind(globalThis));
472
+ const AbortControllerCtor = targetWindow.AbortController || globalThis.AbortController;
473
+ if (!fetcher || !AbortControllerCtor) {
474
+ return false;
475
+ }
476
+ try {
477
+ const parsed = new URL(workerUrl, documentRef.baseURI || targetWindow.location.href);
478
+ if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
479
+ return false;
480
+ }
481
+ }
482
+ catch {
483
+ return false;
484
+ }
485
+ const controller = new AbortControllerCtor();
486
+ const timer = targetWindow.setTimeout(() => controller.abort(), PDF_WORKER_PROBE_TIMEOUT_MS);
487
+ try {
488
+ const response = await fetcher(workerUrl, {
489
+ method: 'HEAD',
490
+ cache: 'no-cache',
491
+ signal: controller.signal,
492
+ });
493
+ if (response.ok) {
494
+ return isJavaScriptLikeResponse(response);
495
+ }
496
+ if (response.status !== 405 && response.status !== 501) {
497
+ return false;
498
+ }
499
+ const fallbackResponse = await fetcher(workerUrl, {
500
+ method: 'GET',
501
+ cache: 'no-cache',
502
+ headers: { Range: 'bytes=0-0' },
503
+ signal: controller.signal,
504
+ });
505
+ return (fallbackResponse.ok || fallbackResponse.status === 206) &&
506
+ isJavaScriptLikeResponse(fallbackResponse);
507
+ }
508
+ catch {
509
+ return false;
510
+ }
511
+ finally {
512
+ targetWindow.clearTimeout(timer);
513
+ }
514
+ };
515
+ const createPdfWorker = async () => {
516
+ const workerUrl = resolvePdfWorkerUrl(options, documentRef.URL || undefined);
517
+ const hasExplicitWorkerUrl = isConfiguredUrl(options === null || options === void 0 ? void 0 : options.workerUrl);
518
+ const shouldUseRealWorker = !!(targetWindow === null || targetWindow === void 0 ? void 0 : targetWindow.Worker) &&
519
+ (hasExplicitWorkerUrl || await canUseResolvedPdfWorkerUrl(workerUrl));
520
+ if (shouldUseRealWorker) {
521
+ GlobalWorkerOptions.workerSrc = workerUrl;
522
+ try {
523
+ const worker = PdfJsWorker.create({ name: 'file-viewer-pdf-worker' });
524
+ await worker.promise;
525
+ return worker;
526
+ }
527
+ catch (error) {
528
+ console.warn('[file-viewer] PDF Worker 初始化失败,改用包内 PDF.js 兜底。', error);
529
+ }
442
530
  }
443
- GlobalWorkerOptions.workerSrc = resolvePdfWorkerUrl(options, documentRef.URL || undefined);
444
531
  try {
445
- return PdfJsWorker.create({ name: 'file-viewer-pdf-worker' });
532
+ await installBundledPdfFakeWorker();
446
533
  }
447
534
  catch (error) {
448
- console.warn('[file-viewer] PDF Worker 无法创建,回退到 PDF.js 默认加载策略。', error);
449
- return null;
535
+ console.warn('[file-viewer] PDF.js 包内 worker 兜底加载失败,继续使用 PDF.js 默认策略。', error);
536
+ GlobalWorkerOptions.workerSrc = workerUrl;
450
537
  }
538
+ return null;
451
539
  };
452
540
  const resolvePdfSearchWaiters = (state) => {
453
541
  const waiters = pdfSearchWaiters;
@@ -889,7 +977,7 @@ export default async function renderPdf(buffer, target, context) {
889
977
  if (!(context === null || context === void 0 ? void 0 : context.streamUrl) && !buffer.byteLength) {
890
978
  throw new Error(t('pdf.error.missingSource'));
891
979
  }
892
- const worker = createPdfWorker();
980
+ const worker = await createPdfWorker();
893
981
  const pdfAssets = resolveFileViewerPdfAssetUrls(options, documentRef.URL || documentRef.baseURI);
894
982
  const source = (context === null || context === void 0 ? void 0 : context.streamUrl)
895
983
  ? {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@file-viewer/renderer-pdf",
3
- "version": "2.1.7",
3
+ "version": "2.1.8",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Standalone PDF renderer plugin for Flyfish File Viewer powered by PDF.js.",
@@ -54,7 +54,7 @@
54
54
  "LICENSE"
55
55
  ],
56
56
  "dependencies": {
57
- "@file-viewer/core": "^2.1.7",
57
+ "@file-viewer/core": "^2.1.8",
58
58
  "pdfjs-dist": "^6.0.227"
59
59
  },
60
60
  "devDependencies": {