@adoptai/genui-components 0.1.67 → 0.1.68

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.
@@ -443,13 +443,73 @@ var init_Markdown = __esm({
443
443
  init_theme();
444
444
  }
445
445
  });
446
+ function resolvePdfWorkerSrc(pdfjs2) {
447
+ const override = typeof window !== "undefined" ? window.__GENUI_PDF_WORKER_SRC__ : void 0;
448
+ const current = pdfjs2.GlobalWorkerOptions.workerSrc;
449
+ const isConfigured = !!current && current !== "pdf.worker.mjs";
450
+ if (override) {
451
+ pdfjs2.GlobalWorkerOptions.workerSrc = override;
452
+ } else if (!isConfigured) {
453
+ pdfjs2.GlobalWorkerOptions.workerSrc = `https://cdn.jsdelivr.net/npm/pdfjs-dist@${pdfjs2.version}/build/pdf.worker.min.mjs`;
454
+ }
455
+ return pdfjs2.GlobalWorkerOptions.workerSrc;
456
+ }
457
+ function probePdfWorker() {
458
+ if (probe) return probe;
459
+ probe = (async () => {
460
+ if (typeof window === "undefined") return false;
461
+ try {
462
+ const { pdfjs: pdfjs2 } = await import('react-pdf');
463
+ resolvePdfWorkerSrc(pdfjs2);
464
+ const task = pdfjs2.getDocument({ data: new TextEncoder().encode(TINY_PDF) });
465
+ const doc = await Promise.race([
466
+ task.promise,
467
+ new Promise(
468
+ (_, reject) => setTimeout(() => reject(new Error("pdf worker probe timed out")), PROBE_TIMEOUT_MS)
469
+ )
470
+ ]);
471
+ await doc.destroy();
472
+ return true;
473
+ } catch (e) {
474
+ probe = null;
475
+ return false;
476
+ }
477
+ })();
478
+ return probe;
479
+ }
480
+ function usePdfWorkerReady(enabled) {
481
+ const [ready, setReady] = useState(null);
482
+ useEffect(() => {
483
+ let cancelled = false;
484
+ probePdfWorker().then((ok) => {
485
+ if (!cancelled) setReady(ok);
486
+ });
487
+ return () => {
488
+ cancelled = true;
489
+ };
490
+ }, [enabled]);
491
+ return ready ;
492
+ }
493
+ var TINY_PDF, PROBE_TIMEOUT_MS, probe;
494
+ var init_pdfWorkerProbe = __esm({
495
+ "src/shared/viewers/pdfWorkerProbe.ts"() {
496
+ "use client";
497
+ TINY_PDF = `%PDF-1.1
498
+ 1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj
499
+ 2 0 obj<</Type/Pages/Kids[3 0 R]/Count 1>>endobj
500
+ 3 0 obj<</Type/Page/Parent 2 0 R/MediaBox[0 0 3 3]>>endobj
501
+ trailer<</Root 1 0 R>>`;
502
+ PROBE_TIMEOUT_MS = 5e3;
503
+ probe = null;
504
+ }
505
+ });
446
506
 
447
507
  // src/composites/document-preview/PdfViewer.tsx
448
508
  var PdfViewer_exports = {};
449
509
  __export(PdfViewer_exports, {
450
510
  PdfViewer: () => PdfViewer
451
511
  });
452
- function PdfViewer({ url, base64, onLoadSuccess }) {
512
+ function PdfViewer({ url, base64, onLoadSuccess, onLoadError }) {
453
513
  const { BORDER: BORDER2, MUTED: MUTED2, SURFACE: SURFACE2 } = useTheme();
454
514
  const [numPages, setNumPages] = useState(0);
455
515
  const [currentPage, setCurrentPage] = useState(1);
@@ -529,23 +589,34 @@ function PdfViewer({ url, base64, onLoadSuccess }) {
529
589
  ] }),
530
590
  /* @__PURE__ */ jsxs("div", { style: { overflow: "auto", width: "100%", display: "flex", justifyContent: "center", padding: "16px" }, children: [
531
591
  loading && /* @__PURE__ */ jsx("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", height: "200px", color: MUTED2, fontSize: "13px" }, children: "Loading PDF..." }),
532
- /* @__PURE__ */ jsx(Document, { file: base64 ? `data:application/pdf;base64,${base64}` : url, onLoadSuccess: handleLoad, loading: "", children: /* @__PURE__ */ jsx(
533
- Page,
592
+ /* @__PURE__ */ jsx(
593
+ Document,
534
594
  {
535
- pageNumber: currentPage,
536
- width: 540,
537
- renderTextLayer: true,
538
- renderAnnotationLayer: true
595
+ file: base64 ? `data:application/pdf;base64,${base64}` : url,
596
+ onLoadSuccess: handleLoad,
597
+ onLoadError,
598
+ loading: "",
599
+ error: "",
600
+ children: /* @__PURE__ */ jsx(
601
+ Page,
602
+ {
603
+ pageNumber: currentPage,
604
+ width: 540,
605
+ renderTextLayer: true,
606
+ renderAnnotationLayer: true
607
+ }
608
+ )
539
609
  }
540
- ) })
610
+ )
541
611
  ] })
542
612
  ] });
543
613
  }
544
614
  var init_PdfViewer = __esm({
545
615
  "src/composites/document-preview/PdfViewer.tsx"() {
546
616
  "use client";
617
+ init_pdfWorkerProbe();
547
618
  init_ThemeContext();
548
- pdfjs.GlobalWorkerOptions.workerSrc = `https://unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs`;
619
+ resolvePdfWorkerSrc(pdfjs);
549
620
  }
550
621
  });
551
622
 
@@ -1328,6 +1399,7 @@ function isExpirySoon(expiresAt) {
1328
1399
 
1329
1400
  // src/shared/viewers/PreviewHost.tsx
1330
1401
  init_ThemeContext();
1402
+ init_pdfWorkerProbe();
1331
1403
  var PdfViewer2 = lazy(
1332
1404
  () => Promise.resolve().then(() => (init_PdfViewer(), PdfViewer_exports)).then((m) => ({ default: m.PdfViewer }))
1333
1405
  );
@@ -1339,6 +1411,19 @@ var TextViewer2 = lazy(() => Promise.resolve().then(() => (init_TextViewer(), Te
1339
1411
  var DocxViewer2 = lazy(() => Promise.resolve().then(() => (init_DocxViewer(), DocxViewer_exports)).then((m) => ({ default: m.DocxViewer })));
1340
1412
  var PEEK_ROWS = 20;
1341
1413
  var PEEK_LINES = 40;
1414
+ function GatedPdfViewer({ source }) {
1415
+ const { MUTED: MUTED2 } = useTheme();
1416
+ const [failed, setFailed] = useState(false);
1417
+ const workerReady = usePdfWorkerReady(true);
1418
+ const ready = failed ? false : workerReady;
1419
+ if (ready === null) {
1420
+ return /* @__PURE__ */ jsx("div", { style: { padding: "24px", color: MUTED2, fontSize: "13px", textAlign: "center" }, children: "Loading preview\u2026" });
1421
+ }
1422
+ if (ready === false) {
1423
+ return /* @__PURE__ */ jsx("div", { style: { padding: "24px", color: MUTED2, fontSize: "13px", textAlign: "center" }, children: "Preview unavailable \u2014 download the file to view it." });
1424
+ }
1425
+ return /* @__PURE__ */ jsx(PdfViewer2, { url: source.url, base64: source.base64, onLoadError: () => setFailed(true) });
1426
+ }
1342
1427
  function PreviewHost({ kind, source, mode = "full" }) {
1343
1428
  const { MUTED: MUTED2 } = useTheme();
1344
1429
  const peek = mode === "peek";
@@ -1346,7 +1431,7 @@ function PreviewHost({ kind, source, mode = "full" }) {
1346
1431
  let viewer = null;
1347
1432
  switch (kind) {
1348
1433
  case "pdf":
1349
- viewer = /* @__PURE__ */ jsx(PdfViewer2, { url: source.url, base64: source.base64 });
1434
+ viewer = /* @__PURE__ */ jsx(GatedPdfViewer, { source });
1350
1435
  break;
1351
1436
  case "excel":
1352
1437
  viewer = /* @__PURE__ */ jsx(ExcelViewer2, { url: source.url, base64: source.base64 });