@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.
@@ -470,13 +470,73 @@ var init_Markdown = __esm({
470
470
  init_theme();
471
471
  }
472
472
  });
473
+ function resolvePdfWorkerSrc(pdfjs2) {
474
+ const override = typeof window !== "undefined" ? window.__GENUI_PDF_WORKER_SRC__ : void 0;
475
+ const current = pdfjs2.GlobalWorkerOptions.workerSrc;
476
+ const isConfigured = !!current && current !== "pdf.worker.mjs";
477
+ if (override) {
478
+ pdfjs2.GlobalWorkerOptions.workerSrc = override;
479
+ } else if (!isConfigured) {
480
+ pdfjs2.GlobalWorkerOptions.workerSrc = `https://cdn.jsdelivr.net/npm/pdfjs-dist@${pdfjs2.version}/build/pdf.worker.min.mjs`;
481
+ }
482
+ return pdfjs2.GlobalWorkerOptions.workerSrc;
483
+ }
484
+ function probePdfWorker() {
485
+ if (probe) return probe;
486
+ probe = (async () => {
487
+ if (typeof window === "undefined") return false;
488
+ try {
489
+ const { pdfjs: pdfjs2 } = await import('react-pdf');
490
+ resolvePdfWorkerSrc(pdfjs2);
491
+ const task = pdfjs2.getDocument({ data: new TextEncoder().encode(TINY_PDF) });
492
+ const doc = await Promise.race([
493
+ task.promise,
494
+ new Promise(
495
+ (_, reject) => setTimeout(() => reject(new Error("pdf worker probe timed out")), PROBE_TIMEOUT_MS)
496
+ )
497
+ ]);
498
+ await doc.destroy();
499
+ return true;
500
+ } catch (e) {
501
+ probe = null;
502
+ return false;
503
+ }
504
+ })();
505
+ return probe;
506
+ }
507
+ function usePdfWorkerReady(enabled) {
508
+ const [ready, setReady] = React10.useState(null);
509
+ React10.useEffect(() => {
510
+ let cancelled = false;
511
+ probePdfWorker().then((ok) => {
512
+ if (!cancelled) setReady(ok);
513
+ });
514
+ return () => {
515
+ cancelled = true;
516
+ };
517
+ }, [enabled]);
518
+ return ready ;
519
+ }
520
+ var TINY_PDF, PROBE_TIMEOUT_MS, probe;
521
+ var init_pdfWorkerProbe = __esm({
522
+ "src/shared/viewers/pdfWorkerProbe.ts"() {
523
+ "use client";
524
+ TINY_PDF = `%PDF-1.1
525
+ 1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj
526
+ 2 0 obj<</Type/Pages/Kids[3 0 R]/Count 1>>endobj
527
+ 3 0 obj<</Type/Page/Parent 2 0 R/MediaBox[0 0 3 3]>>endobj
528
+ trailer<</Root 1 0 R>>`;
529
+ PROBE_TIMEOUT_MS = 5e3;
530
+ probe = null;
531
+ }
532
+ });
473
533
 
474
534
  // src/composites/document-preview/PdfViewer.tsx
475
535
  var PdfViewer_exports = {};
476
536
  __export(PdfViewer_exports, {
477
537
  PdfViewer: () => PdfViewer
478
538
  });
479
- function PdfViewer({ url, base64, onLoadSuccess }) {
539
+ function PdfViewer({ url, base64, onLoadSuccess, onLoadError }) {
480
540
  const { BORDER: BORDER2, MUTED: MUTED2, SURFACE: SURFACE2 } = useTheme();
481
541
  const [numPages, setNumPages] = React10.useState(0);
482
542
  const [currentPage, setCurrentPage] = React10.useState(1);
@@ -556,23 +616,34 @@ function PdfViewer({ url, base64, onLoadSuccess }) {
556
616
  ] }),
557
617
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { overflow: "auto", width: "100%", display: "flex", justifyContent: "center", padding: "16px" }, children: [
558
618
  loading && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", height: "200px", color: MUTED2, fontSize: "13px" }, children: "Loading PDF..." }),
559
- /* @__PURE__ */ jsxRuntime.jsx(reactPdf.Document, { file: base64 ? `data:application/pdf;base64,${base64}` : url, onLoadSuccess: handleLoad, loading: "", children: /* @__PURE__ */ jsxRuntime.jsx(
560
- reactPdf.Page,
619
+ /* @__PURE__ */ jsxRuntime.jsx(
620
+ reactPdf.Document,
561
621
  {
562
- pageNumber: currentPage,
563
- width: 540,
564
- renderTextLayer: true,
565
- renderAnnotationLayer: true
622
+ file: base64 ? `data:application/pdf;base64,${base64}` : url,
623
+ onLoadSuccess: handleLoad,
624
+ onLoadError,
625
+ loading: "",
626
+ error: "",
627
+ children: /* @__PURE__ */ jsxRuntime.jsx(
628
+ reactPdf.Page,
629
+ {
630
+ pageNumber: currentPage,
631
+ width: 540,
632
+ renderTextLayer: true,
633
+ renderAnnotationLayer: true
634
+ }
635
+ )
566
636
  }
567
- ) })
637
+ )
568
638
  ] })
569
639
  ] });
570
640
  }
571
641
  var init_PdfViewer = __esm({
572
642
  "src/composites/document-preview/PdfViewer.tsx"() {
573
643
  "use client";
644
+ init_pdfWorkerProbe();
574
645
  init_ThemeContext();
575
- reactPdf.pdfjs.GlobalWorkerOptions.workerSrc = `https://unpkg.com/pdfjs-dist@${reactPdf.pdfjs.version}/build/pdf.worker.min.mjs`;
646
+ resolvePdfWorkerSrc(reactPdf.pdfjs);
576
647
  }
577
648
  });
578
649
 
@@ -1355,6 +1426,7 @@ function isExpirySoon(expiresAt) {
1355
1426
 
1356
1427
  // src/shared/viewers/PreviewHost.tsx
1357
1428
  init_ThemeContext();
1429
+ init_pdfWorkerProbe();
1358
1430
  var PdfViewer2 = React10.lazy(
1359
1431
  () => Promise.resolve().then(() => (init_PdfViewer(), PdfViewer_exports)).then((m) => ({ default: m.PdfViewer }))
1360
1432
  );
@@ -1366,6 +1438,19 @@ var TextViewer2 = React10.lazy(() => Promise.resolve().then(() => (init_TextView
1366
1438
  var DocxViewer2 = React10.lazy(() => Promise.resolve().then(() => (init_DocxViewer(), DocxViewer_exports)).then((m) => ({ default: m.DocxViewer })));
1367
1439
  var PEEK_ROWS = 20;
1368
1440
  var PEEK_LINES = 40;
1441
+ function GatedPdfViewer({ source }) {
1442
+ const { MUTED: MUTED2 } = useTheme();
1443
+ const [failed, setFailed] = React10.useState(false);
1444
+ const workerReady = usePdfWorkerReady(true);
1445
+ const ready = failed ? false : workerReady;
1446
+ if (ready === null) {
1447
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "24px", color: MUTED2, fontSize: "13px", textAlign: "center" }, children: "Loading preview\u2026" });
1448
+ }
1449
+ if (ready === false) {
1450
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "24px", color: MUTED2, fontSize: "13px", textAlign: "center" }, children: "Preview unavailable \u2014 download the file to view it." });
1451
+ }
1452
+ return /* @__PURE__ */ jsxRuntime.jsx(PdfViewer2, { url: source.url, base64: source.base64, onLoadError: () => setFailed(true) });
1453
+ }
1369
1454
  function PreviewHost({ kind, source, mode = "full" }) {
1370
1455
  const { MUTED: MUTED2 } = useTheme();
1371
1456
  const peek = mode === "peek";
@@ -1373,7 +1458,7 @@ function PreviewHost({ kind, source, mode = "full" }) {
1373
1458
  let viewer = null;
1374
1459
  switch (kind) {
1375
1460
  case "pdf":
1376
- viewer = /* @__PURE__ */ jsxRuntime.jsx(PdfViewer2, { url: source.url, base64: source.base64 });
1461
+ viewer = /* @__PURE__ */ jsxRuntime.jsx(GatedPdfViewer, { source });
1377
1462
  break;
1378
1463
  case "excel":
1379
1464
  viewer = /* @__PURE__ */ jsxRuntime.jsx(ExcelViewer2, { url: source.url, base64: source.base64 });