@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.
@@ -4,7 +4,8 @@ interface PdfViewerProps {
4
4
  url?: string;
5
5
  base64?: string;
6
6
  onLoadSuccess?: (numPages: number) => void;
7
+ onLoadError?: (error: Error) => void;
7
8
  }
8
- export declare function PdfViewer({ url, base64, onLoadSuccess }: PdfViewerProps): import("react/jsx-runtime").JSX.Element;
9
+ export declare function PdfViewer({ url, base64, onLoadSuccess, onLoadError }: PdfViewerProps): import("react/jsx-runtime").JSX.Element;
9
10
  export {};
10
11
  //# sourceMappingURL=PdfViewer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"PdfViewer.d.ts","sourceRoot":"","sources":["../../../src/composites/document-preview/PdfViewer.tsx"],"names":[],"mappings":"AAIA,OAAO,yCAAyC,CAAC;AACjD,OAAO,mCAAmC,CAAC;AAQ3C,UAAU,cAAc;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5C;AAED,wBAAgB,SAAS,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,cAAc,2CAkFvE"}
1
+ {"version":3,"file":"PdfViewer.d.ts","sourceRoot":"","sources":["../../../src/composites/document-preview/PdfViewer.tsx"],"names":[],"mappings":"AAIA,OAAO,yCAAyC,CAAC;AACjD,OAAO,mCAAmC,CAAC;AAU3C,UAAU,cAAc;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACtC;AAED,wBAAgB,SAAS,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,EAAE,cAAc,2CAwFpF"}
@@ -126,13 +126,74 @@ var init_ThemeContext = __esm({
126
126
  GenUIThemeContext = React5.createContext(DEFAULT_TOKENS);
127
127
  }
128
128
  });
129
+ function resolvePdfWorkerSrc(pdfjs2) {
130
+ const override = typeof window !== "undefined" ? window.__GENUI_PDF_WORKER_SRC__ : void 0;
131
+ const current = pdfjs2.GlobalWorkerOptions.workerSrc;
132
+ const isConfigured = !!current && current !== "pdf.worker.mjs";
133
+ if (override) {
134
+ pdfjs2.GlobalWorkerOptions.workerSrc = override;
135
+ } else if (!isConfigured) {
136
+ pdfjs2.GlobalWorkerOptions.workerSrc = `https://cdn.jsdelivr.net/npm/pdfjs-dist@${pdfjs2.version}/build/pdf.worker.min.mjs`;
137
+ }
138
+ return pdfjs2.GlobalWorkerOptions.workerSrc;
139
+ }
140
+ function probePdfWorker() {
141
+ if (probe) return probe;
142
+ probe = (async () => {
143
+ if (typeof window === "undefined") return false;
144
+ try {
145
+ const { pdfjs: pdfjs2 } = await import('react-pdf');
146
+ resolvePdfWorkerSrc(pdfjs2);
147
+ const task = pdfjs2.getDocument({ data: new TextEncoder().encode(TINY_PDF) });
148
+ const doc = await Promise.race([
149
+ task.promise,
150
+ new Promise(
151
+ (_, reject) => setTimeout(() => reject(new Error("pdf worker probe timed out")), PROBE_TIMEOUT_MS)
152
+ )
153
+ ]);
154
+ await doc.destroy();
155
+ return true;
156
+ } catch (e) {
157
+ probe = null;
158
+ return false;
159
+ }
160
+ })();
161
+ return probe;
162
+ }
163
+ function usePdfWorkerReady(enabled) {
164
+ const [ready, setReady] = React5.useState(null);
165
+ React5.useEffect(() => {
166
+ if (!enabled) return;
167
+ let cancelled = false;
168
+ probePdfWorker().then((ok) => {
169
+ if (!cancelled) setReady(ok);
170
+ });
171
+ return () => {
172
+ cancelled = true;
173
+ };
174
+ }, [enabled]);
175
+ return enabled ? ready : null;
176
+ }
177
+ var TINY_PDF, PROBE_TIMEOUT_MS, probe;
178
+ var init_pdfWorkerProbe = __esm({
179
+ "src/shared/viewers/pdfWorkerProbe.ts"() {
180
+ "use client";
181
+ TINY_PDF = `%PDF-1.1
182
+ 1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj
183
+ 2 0 obj<</Type/Pages/Kids[3 0 R]/Count 1>>endobj
184
+ 3 0 obj<</Type/Page/Parent 2 0 R/MediaBox[0 0 3 3]>>endobj
185
+ trailer<</Root 1 0 R>>`;
186
+ PROBE_TIMEOUT_MS = 5e3;
187
+ probe = null;
188
+ }
189
+ });
129
190
 
130
191
  // src/composites/document-preview/PdfViewer.tsx
131
192
  var PdfViewer_exports = {};
132
193
  __export(PdfViewer_exports, {
133
194
  PdfViewer: () => PdfViewer
134
195
  });
135
- function PdfViewer({ url, base64, onLoadSuccess }) {
196
+ function PdfViewer({ url, base64, onLoadSuccess, onLoadError }) {
136
197
  const { BORDER: BORDER2, MUTED: MUTED2, SURFACE: SURFACE2 } = useTheme();
137
198
  const [numPages, setNumPages] = React5.useState(0);
138
199
  const [currentPage, setCurrentPage] = React5.useState(1);
@@ -212,23 +273,34 @@ function PdfViewer({ url, base64, onLoadSuccess }) {
212
273
  ] }),
213
274
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { overflow: "auto", width: "100%", display: "flex", justifyContent: "center", padding: "16px" }, children: [
214
275
  loading && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", height: "200px", color: MUTED2, fontSize: "13px" }, children: "Loading PDF..." }),
215
- /* @__PURE__ */ jsxRuntime.jsx(reactPdf.Document, { file: base64 ? `data:application/pdf;base64,${base64}` : url, onLoadSuccess: handleLoad, loading: "", children: /* @__PURE__ */ jsxRuntime.jsx(
216
- reactPdf.Page,
276
+ /* @__PURE__ */ jsxRuntime.jsx(
277
+ reactPdf.Document,
217
278
  {
218
- pageNumber: currentPage,
219
- width: 540,
220
- renderTextLayer: true,
221
- renderAnnotationLayer: true
279
+ file: base64 ? `data:application/pdf;base64,${base64}` : url,
280
+ onLoadSuccess: handleLoad,
281
+ onLoadError,
282
+ loading: "",
283
+ error: "",
284
+ children: /* @__PURE__ */ jsxRuntime.jsx(
285
+ reactPdf.Page,
286
+ {
287
+ pageNumber: currentPage,
288
+ width: 540,
289
+ renderTextLayer: true,
290
+ renderAnnotationLayer: true
291
+ }
292
+ )
222
293
  }
223
- ) })
294
+ )
224
295
  ] })
225
296
  ] });
226
297
  }
227
298
  var init_PdfViewer = __esm({
228
299
  "src/composites/document-preview/PdfViewer.tsx"() {
229
300
  "use client";
301
+ init_pdfWorkerProbe();
230
302
  init_ThemeContext();
231
- reactPdf.pdfjs.GlobalWorkerOptions.workerSrc = `https://unpkg.com/pdfjs-dist@${reactPdf.pdfjs.version}/build/pdf.worker.min.mjs`;
303
+ resolvePdfWorkerSrc(reactPdf.pdfjs);
232
304
  }
233
305
  });
234
306
 
@@ -952,6 +1024,7 @@ function useFullscreen(ref) {
952
1024
  // src/composites/document-preview/resolver.tsx
953
1025
  init_theme();
954
1026
  init_ThemeContext();
1027
+ init_pdfWorkerProbe();
955
1028
  var PdfViewer2 = React5__default.default.lazy(
956
1029
  () => Promise.resolve().then(() => (init_PdfViewer(), PdfViewer_exports)).then((m) => ({ default: m.PdfViewer }))
957
1030
  );
@@ -1015,8 +1088,14 @@ function DocumentPreviewResolver(p) {
1015
1088
  const totalPages = ((_c = p.pages) != null ? _c : []).length;
1016
1089
  const page = p.pages[currentPage];
1017
1090
  const pageHighlights = ((_d = p.highlights) != null ? _d : []).filter((h) => h.pageIndex === currentPage);
1091
+ const [pdfFailed, setPdfFailed] = React5.useState(false);
1092
+ const pdfWorkerReady = usePdfWorkerReady(hasRealFile && isPdf);
1093
+ const pdfReady = pdfFailed ? false : pdfWorkerReady;
1094
+ const showPdfViewer = hasRealFile && isPdf && pdfReady === true;
1095
+ const pdfPending = hasRealFile && isPdf && pdfReady === null;
1018
1096
  const handlePdfLoad = React5.useCallback(() => {
1019
1097
  }, []);
1098
+ const handlePdfError = React5.useCallback(() => setPdfFailed(true), []);
1020
1099
  const handleExcelLoad = React5.useCallback(() => {
1021
1100
  }, []);
1022
1101
  return /* @__PURE__ */ jsxRuntime.jsx(ComponentActions, { filename: (_e = p.title) != null ? _e : "document-preview", children: /* @__PURE__ */ jsxRuntime.jsxs(
@@ -1110,7 +1189,7 @@ function DocumentPreviewResolver(p) {
1110
1189
  children: pg.label
1111
1190
  },
1112
1191
  i
1113
- )) }) : !hasRealFile && totalPages > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", padding: "6px 14px", borderLeft: `1px solid ${BORDER2}`, borderRight: `1px solid ${BORDER2}`, background: SURFACE2 }, children: [
1192
+ )) }) : (!hasRealFile || pdfReady === false) && totalPages > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", padding: "6px 14px", borderLeft: `1px solid ${BORDER2}`, borderRight: `1px solid ${BORDER2}`, background: SURFACE2 }, children: [
1114
1193
  /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => setCurrentPage(Math.max(0, currentPage - 1)), disabled: currentPage === 0, style: { border: `1px solid ${BORDER2}`, borderRadius: "4px", padding: "2px 8px", background: SURFACE2, cursor: "pointer", fontSize: "12px", color: currentPage === 0 ? BORDER2 : MUTED2 }, children: "\u2190" }),
1115
1194
  /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: "12px", color: MUTED2 }, children: [
1116
1195
  currentPage + 1,
@@ -1130,7 +1209,7 @@ function DocumentPreviewResolver(p) {
1130
1209
  display: "flex",
1131
1210
  flexDirection: "column"
1132
1211
  }, children: [
1133
- hasRealFile && isPdf ? /* @__PURE__ */ jsxRuntime.jsx(React5.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(PdfViewer2, { url: (_q = p.source) == null ? void 0 : _q.url, base64: (_r = p.source) == null ? void 0 : _r.base64, onLoadSuccess: handlePdfLoad }) }) : hasRealFile && isExcel ? /* @__PURE__ */ jsxRuntime.jsx(React5.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(ExcelViewer2, { url: (_s = p.source) == null ? void 0 : _s.url, base64: (_t = p.source) == null ? void 0 : _t.base64, onLoadSuccess: handleExcelLoad }) }) : (page == null ? void 0 : page.imageUrl) ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "20px" }, children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: page.imageUrl, alt: page.label, style: { maxWidth: "100%", borderRadius: "4px" } }) }) : (page == null ? void 0 : page.content) ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontFamily: "var(--font-sans, system-ui)", fontSize: "13px", color: "var(--foreground)", lineHeight: 1.6, margin: 0, padding: "20px" }, children: /* @__PURE__ */ jsxRuntime.jsx(Markdown, { content: page.content }) }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", height: "120px", color: MUTED2, fontSize: "13px" }, children: [
1212
+ showPdfViewer ? /* @__PURE__ */ jsxRuntime.jsx(React5.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(PdfViewer2, { url: (_q = p.source) == null ? void 0 : _q.url, base64: (_r = p.source) == null ? void 0 : _r.base64, onLoadSuccess: handlePdfLoad, onLoadError: handlePdfError }) }) : pdfPending ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", height: "200px", color: MUTED2, fontSize: "13px" }, children: "Loading preview\u2026" }) : hasRealFile && isExcel ? /* @__PURE__ */ jsxRuntime.jsx(React5.Suspense, { fallback: null, children: /* @__PURE__ */ jsxRuntime.jsx(ExcelViewer2, { url: (_s = p.source) == null ? void 0 : _s.url, base64: (_t = p.source) == null ? void 0 : _t.base64, onLoadSuccess: handleExcelLoad }) }) : (page == null ? void 0 : page.imageUrl) ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "20px" }, children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: page.imageUrl, alt: page.label, style: { maxWidth: "100%", borderRadius: "4px" } }) }) : (page == null ? void 0 : page.content) ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontFamily: "var(--font-sans, system-ui)", fontSize: "13px", color: "var(--foreground)", lineHeight: 1.6, margin: 0, padding: "20px" }, children: /* @__PURE__ */ jsxRuntime.jsx(Markdown, { content: page.content }) }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", height: "120px", color: MUTED2, fontSize: "13px" }, children: [
1134
1213
  "No content available for ",
1135
1214
  (_u = page == null ? void 0 : page.label) != null ? _u : "this page"
1136
1215
  ] }),