@lobehub/lobehub 2.0.0-next.345 → 2.0.0-next.346

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/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [Version 2.0.0-next.346](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.345...v2.0.0-next.346)
6
+
7
+ <sup>Released on **2026-01-23**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **pdf**: Upgrade pdfjs-dist and react-pdf to v5.x.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's fixed
19
+
20
+ - **pdf**: Upgrade pdfjs-dist and react-pdf to v5.x, closes [#11686](https://github.com/lobehub/lobe-chat/issues/11686) ([2b620df](https://github.com/lobehub/lobe-chat/commit/2b620df))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
5
30
  ## [Version 2.0.0-next.345](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.344...v2.0.0-next.345)
6
31
 
7
32
  <sup>Released on **2026-01-23**</sup>
package/CLAUDE.md CHANGED
@@ -61,9 +61,11 @@ see @.cursor/rules/typescript.mdc
61
61
  - **Dev**: Translate `locales/zh-CN/namespace.json` and `locales/en-US/namespace.json` locales file only for dev preview
62
62
  - DON'T run `pnpm i18n`, let CI auto handle it
63
63
 
64
- ## Linear Issue Management(ignore if not installed linear mcp)
64
+ ## Linear Issue Management (search tools first; ignore if not installed)
65
65
 
66
- Read @.cursor/rules/linear.mdc when working with Linear issues.
66
+ ClaudeCode may not inject MCP tools until they are discovered/used.\
67
+ Before applying Linear workflows, **use tool search** to confirm `linear-server` exists (e.g. search `linear` / `mcp__linear-server__`). If not found, treat it as not installed.\
68
+ Then read `@.cursor/rules/linear.mdc` when working with Linear issues.
67
69
 
68
70
  ## Rules Index
69
71
 
package/changelog/v1.json CHANGED
@@ -1,4 +1,9 @@
1
1
  [
2
+ {
3
+ "children": {},
4
+ "date": "2026-01-23",
5
+ "version": "2.0.0-next.346"
6
+ },
2
7
  {
3
8
  "children": {
4
9
  "features": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/lobehub",
3
- "version": "2.0.0-next.345",
3
+ "version": "2.0.0-next.346",
4
4
  "description": "LobeHub - an open-source,comprehensive AI Agent framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
5
5
  "keywords": [
6
6
  "framework",
@@ -133,6 +133,7 @@
133
133
  ]
134
134
  },
135
135
  "overrides": {
136
+ "pdfjs-dist": "5.4.530",
136
137
  "stylelint-config-clean-order": "7.0.0"
137
138
  },
138
139
  "dependencies": {
@@ -206,11 +207,12 @@
206
207
  "@lobehub/tts": "^4.0.2",
207
208
  "@lobehub/ui": "^4.27.4",
208
209
  "@modelcontextprotocol/sdk": "^1.25.1",
210
+ "@napi-rs/canvas": "^0.1.88",
209
211
  "@neondatabase/serverless": "^1.0.2",
210
212
  "@next/third-parties": "^16.1.1",
211
213
  "@opentelemetry/exporter-jaeger": "^2.2.0",
212
214
  "@opentelemetry/winston-transport": "^0.19.0",
213
- "@react-pdf/renderer": "^4.3.1",
215
+ "@react-pdf/renderer": "^4.3.2",
214
216
  "@react-three/drei": "^10.7.7",
215
217
  "@react-three/fiber": "^9.4.2",
216
218
  "@saintno/comfyui-sdk": "^0.2.49",
@@ -296,7 +298,7 @@
296
298
  "path-browserify-esm": "^1.0.6",
297
299
  "pathe": "^2.0.3",
298
300
  "pdf-parse": "^1.1.4",
299
- "pdfjs-dist": "4.8.69",
301
+ "pdfjs-dist": "5.4.530",
300
302
  "pdfkit": "^0.17.2",
301
303
  "pg": "^8.16.3",
302
304
  "pino": "^10.1.0",
@@ -316,7 +318,7 @@
316
318
  "react-hotkeys-hook": "^5.2.1",
317
319
  "react-i18next": "^16.5.0",
318
320
  "react-lazy-load": "^4.0.1",
319
- "react-pdf": "^9.2.1",
321
+ "react-pdf": "^10.3.0",
320
322
  "react-responsive": "^10.0.1",
321
323
  "react-rnd": "^10.5.2",
322
324
  "react-router-dom": "^7.11.0",
@@ -30,7 +30,7 @@
30
30
  "debug": "^4.4.3",
31
31
  "mammoth": "^1.11.0",
32
32
  "officeparser": "5.1.1",
33
- "pdfjs-dist": "4.10.38",
33
+ "pdfjs-dist": "5.4.530",
34
34
  "word-extractor": "^1.0.4",
35
35
  "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
36
36
  "yauzl": "^3.2.0"
@@ -2,10 +2,8 @@ import debug from 'debug';
2
2
  import { stat } from 'node:fs/promises';
3
3
  import * as path from 'node:path';
4
4
 
5
- import { fileLoaders } from './loaders';
6
- import { TextLoader } from './loaders/text';
7
- import { FileDocument, FileMetadata, SupportedFileType } from './types';
8
- import type { DocumentPage, FileLoaderInterface } from './types';
5
+ import { getFileLoader } from './loaders';
6
+ import type { DocumentPage, FileDocument, FileMetadata, SupportedFileType } from './types';
9
7
  import { isTextReadableFile } from './utils/isTextReadableFile';
10
8
 
11
9
  const log = debug('file-loaders:loadFile');
@@ -64,9 +62,6 @@ const getFileType = (filePath: string): SupportedFileType | undefined => {
64
62
  }
65
63
  };
66
64
 
67
- // Default fallback loader class
68
- const DefaultLoader = TextLoader;
69
-
70
65
  /**
71
66
  * Loads a file from the specified path, automatically detecting the file type
72
67
  * and using the appropriate loader class.
@@ -113,18 +108,18 @@ export const loadFile = async (
113
108
  source,
114
109
  });
115
110
 
116
- const paserType = getFileType(filePath);
117
- log('Parser type determined as:', paserType);
111
+ const parserType = getFileType(filePath);
112
+ log('Parser type determined as:', parserType);
118
113
 
119
- // Select the loader CLASS based on the determined fileType, fallback to DefaultLoader
120
- const LoaderClass: new () => FileLoaderInterface = paserType
121
- ? fileLoaders[paserType]
122
- : DefaultLoader;
114
+ // Use lazy loading to get the loader class - this prevents heavy dependencies
115
+ // like pdfjs-dist from being loaded until they're actually needed
116
+ const loaderType = parserType ?? 'txt';
117
+ const LoaderClass = await getFileLoader(loaderType);
123
118
  log('Selected loader class:', LoaderClass.name);
124
119
 
125
- if (!paserType) {
120
+ if (!parserType) {
126
121
  console.warn(
127
- `No specific loader found for file type '${fileType}'. Using default loader (${DefaultLoader.name}) as fallback.`,
122
+ `No specific loader found for file type '${fileType}'. Using default loader (TextLoader) as fallback.`,
128
123
  );
129
124
  }
130
125
 
@@ -1,21 +1,70 @@
1
- import { FileLoaderInterface, SupportedFileType } from '../types';
2
- import { DocLoader } from './doc';
3
- import { DocxLoader } from './docx';
4
- // import { EpubLoader } from './epub';
5
- import { ExcelLoader } from './excel';
6
- import { PdfLoader } from './pdf';
7
- import { PptxLoader } from './pptx';
8
- import { TextLoader } from './text';
1
+ import type { FileLoaderInterface, SupportedFileType } from '../types';
9
2
 
10
- // Loader configuration map
11
- // Key: file extension (lowercase, without leading dot) or specific type name
12
- // Value: Loader Class implementing FileLoaderInterface
13
- export const fileLoaders: Record<SupportedFileType, new () => FileLoaderInterface> = {
14
- doc: DocLoader,
15
- docx: DocxLoader,
16
- // epub: EpubLoader,
17
- excel: ExcelLoader,
18
- pdf: PdfLoader,
19
- pptx: PptxLoader,
20
- txt: TextLoader,
3
+ // Lazy loader factory type - returns a Promise that resolves to the loader class
4
+ type LazyLoaderFactory = () => Promise<new () => FileLoaderInterface>;
5
+
6
+ // Loader configuration map using lazy imports
7
+ // This prevents pdfjs-dist from being loaded at module initialization
8
+ // and only loads it when PDF files need to be processed
9
+ const lazyFileLoaders: Record<SupportedFileType, LazyLoaderFactory> = {
10
+ doc: async () => {
11
+ const { DocLoader } = await import('./doc');
12
+ return DocLoader;
13
+ },
14
+ docx: async () => {
15
+ const { DocxLoader } = await import('./docx');
16
+ return DocxLoader;
17
+ },
18
+ excel: async () => {
19
+ const { ExcelLoader } = await import('./excel');
20
+ return ExcelLoader;
21
+ },
22
+ pdf: async () => {
23
+ // Polyfill DOMMatrix for Node.js environment before importing pdfjs-dist
24
+ // pdfjs-dist 5.x uses DOMMatrix at module initialization which doesn't exist in Node.js
25
+ if (typeof globalThis.DOMMatrix === 'undefined') {
26
+ try {
27
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
28
+ const canvas = require('@napi-rs/canvas');
29
+ globalThis.DOMMatrix = canvas.DOMMatrix;
30
+ globalThis.DOMPoint = canvas.DOMPoint;
31
+ globalThis.DOMRect = canvas.DOMRect;
32
+ globalThis.Path2D = canvas.Path2D;
33
+ } catch {
34
+ // @napi-rs/canvas not available, pdfjs-dist may fail if DOMMatrix is needed
35
+ }
36
+ }
37
+ const { PdfLoader } = await import('./pdf');
38
+ return PdfLoader;
39
+ },
40
+ pptx: async () => {
41
+ const { PptxLoader } = await import('./pptx');
42
+ return PptxLoader;
43
+ },
44
+ txt: async () => {
45
+ const { TextLoader } = await import('./text');
46
+ return TextLoader;
47
+ },
48
+ };
49
+
50
+ /**
51
+ * Get a file loader class for the specified file type.
52
+ * Uses dynamic imports to avoid loading heavy dependencies (like pdfjs-dist) until needed.
53
+ * Falls back to TextLoader if no specific loader is found.
54
+ */
55
+ export const getFileLoader = async (
56
+ fileType: SupportedFileType | string,
57
+ ): Promise<new () => FileLoaderInterface> => {
58
+ const loaderFactory = lazyFileLoaders[fileType as SupportedFileType];
59
+ if (!loaderFactory) {
60
+ // Fallback to TextLoader for unsupported file types
61
+ const { TextLoader } = await import('./text');
62
+ return TextLoader;
63
+ }
64
+ return loaderFactory();
21
65
  };
66
+
67
+ // For backward compatibility - but prefer using getFileLoader for lazy loading
68
+ // This is kept to avoid breaking existing imports, but it will trigger immediate loading
69
+ // of all loaders. Consider migrating to getFileLoader.
70
+ export { lazyFileLoaders as fileLoaderFactories };
@@ -52,7 +52,7 @@ exports[`PdfLoader > should attach document metadata correctly 1`] = `
52
52
  "Title": "test",
53
53
  },
54
54
  "pdfMetadata": null,
55
- "pdfVersion": "4.10.38",
55
+ "pdfVersion": "5.4.530",
56
56
  }
57
57
  `;
58
58
 
@@ -25,7 +25,7 @@ exports[`loadFile Integration Tests > PDF Handling > should load content from a
25
25
  "Title": "test",
26
26
  },
27
27
  "pdfMetadata": null,
28
- "pdfVersion": "4.10.38",
28
+ "pdfVersion": "5.4.530",
29
29
  },
30
30
  },
31
31
  "pages": [
@@ -13,6 +13,7 @@ overrides:
13
13
  '@swagger-api/apidom-reference': 1.1.0
14
14
  jose: ^6.1.3
15
15
  stylelint-config-clean-order: 7.0.0
16
+ pdfjs-dist: 5.4.530
16
17
 
17
18
  patchedDependencies:
18
19
  '@swagger-api/apidom-reference': patches/@swagger-api__apidom-reference.patch
@@ -1,6 +1,6 @@
1
1
  import { type StateCreator } from 'zustand/vanilla';
2
2
 
3
- import { type ResouceManagerMode } from '@/features/ResourceManager';
3
+ import { type ResourceManagerMode } from '@/features/ResourceManager';
4
4
  import { type FilesTabs, SortType } from '@/types/files';
5
5
 
6
6
  import { type State, type ViewMode, initialState } from './initialState';
@@ -67,7 +67,7 @@ export interface Action {
67
67
  /**
68
68
  * Set the view mode
69
69
  */
70
- setMode: (mode: ResouceManagerMode) => void;
70
+ setMode: (mode: ResourceManagerMode) => void;
71
71
  /**
72
72
  * Set the pending rename item ID
73
73
  */
@@ -1,4 +1,4 @@
1
- import { type ResouceManagerMode } from '@/features/ResourceManager';
1
+ import { type ResourceManagerMode } from '@/features/ResourceManager';
2
2
  import { FilesTabs, SortType } from '@/types/files';
3
3
 
4
4
  export type ViewMode = 'list' | 'masonry';
@@ -39,7 +39,7 @@ export interface State {
39
39
  /**
40
40
  * View mode for displaying resources
41
41
  */
42
- mode: ResouceManagerMode;
42
+ mode: ResourceManagerMode;
43
43
  /**
44
44
  * ID of item currently being renamed (for inline editing)
45
45
  */
@@ -1,6 +1,6 @@
1
1
  import { type StateCreator } from 'zustand/vanilla';
2
2
 
3
- import { type ResouceManagerMode } from '@/features/ResourceManager';
3
+ import { type ResourceManagerMode } from '@/features/ResourceManager';
4
4
 
5
5
  import { type State, initialState } from './initialState';
6
6
 
@@ -12,7 +12,7 @@ export interface Action {
12
12
  /**
13
13
  * Set the view mode
14
14
  */
15
- setMode: (mode: ResouceManagerMode) => void;
15
+ setMode: (mode: ResourceManagerMode) => void;
16
16
  /**
17
17
  * Set selected file IDs
18
18
  */
@@ -1,8 +1,8 @@
1
- import { type ResouceManagerMode } from '@/features/ResourceManager';
1
+ import { type ResourceManagerMode } from '@/features/ResourceManager';
2
2
 
3
3
  export interface State {
4
4
  currentViewItemId?: string;
5
- mode: ResouceManagerMode;
5
+ mode: ResourceManagerMode;
6
6
  selectedFileIds: string[];
7
7
  }
8
8
 
@@ -1,22 +1,19 @@
1
1
  'use client';
2
2
 
3
3
  import { Flexbox } from '@lobehub/ui';
4
- import type { PDFDocumentProxy } from 'pdfjs-dist';
5
4
  import { Fragment, memo, useCallback, useState } from 'react';
6
5
  import { Document, Page, pdfjs } from 'react-pdf';
7
- import 'react-pdf/dist/esm/Page/AnnotationLayer.css';
8
- import 'react-pdf/dist/esm/Page/TextLayer.css';
6
+ import 'react-pdf/dist/Page/AnnotationLayer.css';
7
+ import 'react-pdf/dist/Page/TextLayer.css';
9
8
 
10
9
  import NeuralNetworkLoading from '@/components/NeuralNetworkLoading';
10
+ import '@/libs/pdfjs/worker';
11
11
  import { lambdaQuery } from '@/libs/trpc/client';
12
12
 
13
13
  import HighlightLayer from './HighlightLayer';
14
14
  import { styles } from './style';
15
15
  import useResizeObserver from './useResizeObserver';
16
16
 
17
- // 如果海外的地址: https://unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.mjs
18
- pdfjs.GlobalWorkerOptions.workerSrc = `https://registry.npmmirror.com/pdfjs-dist/${pdfjs.version}/files/build/pdf.worker.min.mjs`;
19
-
20
17
  const options = {
21
18
  cMapUrl: `https://registry.npmmirror.com/pdfjs-dist/${pdfjs.version}/files/cmaps/`,
22
19
  standardFontDataUrl: `https://registry.npmmirror.com/pdfjs-dist/${pdfjs.version}/files/standard_fonts/`,
@@ -46,8 +43,8 @@ const PDFViewer = memo<PDFViewerProps>(({ url, fileId }) => {
46
43
 
47
44
  useResizeObserver(containerRef, onResize);
48
45
 
49
- const onDocumentLoadSuccess = ({ numPages: nextNumPages }: PDFDocumentProxy) => {
50
- setNumPages(nextNumPages);
46
+ const onDocumentLoadSuccess = (document: unknown) => {
47
+ setNumPages((document as { numPages: number }).numPages);
51
48
  setIsLoaded(true);
52
49
  };
53
50
 
@@ -41,7 +41,6 @@ const styles = createStaticStyles(({ css }) => {
41
41
  cursor: pointer;
42
42
  min-width: 800px;
43
43
 
44
- /* Hover effect for individual rows */
45
44
  &:hover {
46
45
  background: ${cssVar.colorFillTertiary};
47
46
  }
@@ -194,7 +193,6 @@ const FileListItem = memo<FileListItemProps>(
194
193
  const [isDragging, setIsDragging] = useState(false);
195
194
  const [isOver, setIsOver] = useState(false);
196
195
 
197
- // Memoize computed values that don't change
198
196
  const computedValues = useMemo(() => {
199
197
  const isPDF = fileType?.toLowerCase() === 'pdf' || name?.toLowerCase().endsWith('.pdf');
200
198
  return {
@@ -208,7 +206,6 @@ const FileListItem = memo<FileListItemProps>(
208
206
 
209
207
  const { isSupportedForChunking, isPage, isFolder, emoji } = computedValues;
210
208
 
211
- // Memoize drag data to prevent recreation
212
209
  const dragData = useMemo(
213
210
  () => ({
214
211
  fileType,
@@ -219,7 +216,6 @@ const FileListItem = memo<FileListItemProps>(
219
216
  [fileType, isFolder, name, sourceType],
220
217
  );
221
218
 
222
- // Native HTML5 drag event handlers
223
219
  const handleDragStart = useCallback(
224
220
  (e: DragEvent) => {
225
221
  if (!resourceManagerState.libraryId) {
@@ -264,7 +260,6 @@ const FileListItem = memo<FileListItemProps>(
264
260
  }, []);
265
261
 
266
262
  const handleDrop = useCallback(() => {
267
- // Clear the highlight after drop
268
263
  setIsOver(false);
269
264
  }, []);
270
265
 
@@ -359,7 +354,6 @@ const FileListItem = memo<FileListItemProps>(
359
354
  { replace: true },
360
355
  );
361
356
  } else {
362
- // Set mode to file and store the file ID
363
357
  resourceManagerState.setCurrentViewItemId(id);
364
358
  resourceManagerState.setMode('editor');
365
359
  // Also update URL query parameter for shareable links
@@ -378,7 +372,6 @@ const FileListItem = memo<FileListItemProps>(
378
372
  useEffect(() => {
379
373
  if (pendingRenameItemId === id && isFolder && !isRenaming) {
380
374
  handleRenameStart();
381
- // Clear the pending rename item after triggering
382
375
  resourceManagerState.setPendingRenameItemId(null);
383
376
  }
384
377
  }, [pendingRenameItemId, id, isFolder, resourceManagerState]);
@@ -575,7 +568,6 @@ const FileListItem = memo<FileListItemProps>(
575
568
  },
576
569
  // Custom comparison function to prevent unnecessary re-renders
577
570
  (prevProps, nextProps) => {
578
- // Only re-render if these critical props change
579
571
  return (
580
572
  prevProps.id === nextProps.id &&
581
573
  prevProps.name === nextProps.name &&
@@ -48,7 +48,7 @@ const styles = createStaticStyles(({ css, cssVar }) => {
48
48
  };
49
49
  });
50
50
 
51
- export type ResouceManagerMode = 'editor' | 'explorer' | 'page';
51
+ export type ResourceManagerMode = 'editor' | 'explorer' | 'page';
52
52
 
53
53
  /**
54
54
  * Manage resources. Can be from a certian library.
@@ -1,3 +1,5 @@
1
+ 'use client';
2
+
1
3
  import { LoadingOutlined } from '@ant-design/icons';
2
4
  import { Button, Flexbox } from '@lobehub/ui';
3
5
  import { Input, Modal, Spin } from 'antd';
@@ -5,15 +7,13 @@ import { createStaticStyles, cx } from 'antd-style';
5
7
  import { ChevronLeft, ChevronRight, Expand, FileText } from 'lucide-react';
6
8
  import { memo, useState } from 'react';
7
9
  import { useTranslation } from 'react-i18next';
8
- import { Document, Page, pdfjs } from 'react-pdf';
10
+ import { Document, Page } from 'react-pdf';
9
11
 
10
12
  import { useIsMobile } from '@/hooks/useIsMobile';
13
+ import '@/libs/pdfjs/worker';
11
14
 
12
15
  import { containerStyles } from '../style';
13
16
 
14
- // Set PDF.js worker
15
- pdfjs.GlobalWorkerOptions.workerSrc = `https://registry.npmmirror.com/pdfjs-dist/${pdfjs.version}/files/build/pdf.worker.min.mjs`;
16
-
17
17
  const styles = createStaticStyles(({ css }) => ({
18
18
  containerWrapper: css`
19
19
  position: relative;
@@ -17,16 +17,14 @@ interface CustomNextConfig {
17
17
  export function defineConfig(config: CustomNextConfig) {
18
18
  const isProd = process.env.NODE_ENV === 'production';
19
19
  const buildWithDocker = process.env.DOCKER === 'true';
20
- const isDesktop = process.env.NEXT_PUBLIC_IS_DESKTOP_APP === '1';
20
+
21
21
  const enableReactScan = !!process.env.REACT_SCAN_MONITOR_API_KEY;
22
22
  const shouldUseCSP = process.env.ENABLED_CSP === '1';
23
23
 
24
24
  const isTest =
25
25
  process.env.NODE_ENV === 'test' || process.env.TEST === '1' || process.env.E2E === '1';
26
26
 
27
- // if you need to proxy the api endpoint to remote server
28
-
29
- const isStandaloneMode = buildWithDocker || isDesktop;
27
+ const isStandaloneMode = buildWithDocker || process.env.NEXT_BUILD_STANDALONE === '1';
30
28
 
31
29
  const standaloneConfig: NextConfig = {
32
30
  output: 'standalone',
@@ -38,6 +36,7 @@ export function defineConfig(config: CustomNextConfig) {
38
36
  const nextConfig: NextConfig = {
39
37
  ...(isStandaloneMode ? standaloneConfig : {}),
40
38
  assetPrefix,
39
+
41
40
  compiler: {
42
41
  emotion: true,
43
42
  },
@@ -321,13 +320,14 @@ export function defineConfig(config: CustomNextConfig) {
321
320
  },
322
321
  ...(config.redirects ?? []),
323
322
  ],
324
-
325
323
  // when external packages in dev mode with turbopack, this config will lead to bundle error
324
+ // @napi-rs/canvas is a native module that can't be bundled by Turbopack
325
+ // pdfjs-dist uses @napi-rs/canvas for DOMMatrix polyfill in Node.js environment
326
326
  serverExternalPackages: config.serverExternalPackages
327
327
  ? config.serverExternalPackages
328
- : ['pdfkit'],
328
+ : ['pdfkit', '@napi-rs/canvas', 'pdfjs-dist'],
329
329
 
330
- transpilePackages: ['pdfjs-dist', 'mermaid', 'better-auth-harmony'],
330
+ transpilePackages: ['mermaid', 'better-auth-harmony'],
331
331
  turbopack: {
332
332
  rules: isTest
333
333
  ? void 0
@@ -406,14 +406,13 @@ export function defineConfig(config: CustomNextConfig) {
406
406
 
407
407
  const withBundleAnalyzer = process.env.ANALYZE === 'true' ? analyzer() : noWrapper;
408
408
 
409
- const withPWA =
410
- isProd && !isDesktop
411
- ? withSerwistInit({
412
- register: false,
413
- swDest: 'public/sw.js',
414
- swSrc: 'src/app/sw.ts',
415
- })
416
- : noWrapper;
409
+ const withPWA = isProd
410
+ ? withSerwistInit({
411
+ register: false,
412
+ swDest: 'public/sw.js',
413
+ swSrc: 'src/app/sw.ts',
414
+ })
415
+ : noWrapper;
417
416
 
418
417
  return withBundleAnalyzer(withPWA(nextConfig as NextConfig));
419
418
  }
@@ -0,0 +1 @@
1
+ import 'pdfjs-dist/build/pdf.worker.min.mjs';
@@ -0,0 +1,12 @@
1
+ 'use client';
2
+
3
+ import { pdfjs } from 'react-pdf';
4
+
5
+ pdfjs.GlobalWorkerOptions.workerSrc = `https://registry.npmmirror.com/pdfjs-dist/${pdfjs.version}/files/build/pdf.worker.min.mjs`;
6
+
7
+ // TODO: Re-enable module worker when fully on Turbopack.
8
+ // if (typeof Worker !== 'undefined' && !pdfjs.GlobalWorkerOptions.workerPort) {
9
+ // pdfjs.GlobalWorkerOptions.workerPort = new Worker(new URL('./pdf.worker.ts', import.meta.url), {
10
+ // type: 'module',
11
+ // });
12
+ // }