svelte-pdf-view 0.1.6 → 0.1.7

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.
@@ -2,6 +2,7 @@
2
2
  import { BROWSER } from 'esm-env';
3
3
  import { onDestroy, onMount } from 'svelte';
4
4
  import { getPdfViewerContext, type PdfViewerActions } from './pdf-viewer/context.js';
5
+ import { getPdfJs } from './pdf-viewer/pdfjs-singleton.js';
5
6
  import { rendererStyles } from './pdf-viewer/renderer-styles.js';
6
7
 
7
8
  /** PDF source - can be a URL string, ArrayBuffer, Uint8Array, or Blob */
@@ -44,29 +45,6 @@
44
45
  // Core instances
45
46
  let viewer: import('./pdf-viewer/PDFViewerCore.js').PDFViewerCore | null = null;
46
47
  let findController: import('./pdf-viewer/FindController.js').FindController | null = null;
47
- let pdfjsLib: typeof import('pdfjs-dist/legacy/build/pdf.mjs') | null = null;
48
- let pdfWorker: import('pdfjs-dist/legacy/build/pdf.mjs').PDFWorker | null = null;
49
- let rawWorker: Worker | null = null;
50
-
51
- async function initPdfJs() {
52
- if (!BROWSER) return null;
53
-
54
- // Return cached instance if already initialized
55
- if (pdfjsLib && pdfWorker) return pdfjsLib;
56
-
57
- pdfjsLib = await import('pdfjs-dist/legacy/build/pdf.mjs');
58
-
59
- // Create worker only once using import.meta.url for proper bundler resolution
60
- rawWorker = new Worker(new URL('pdfjs-dist/legacy/build/pdf.worker.mjs', import.meta.url), {
61
- type: 'module'
62
- });
63
- pdfWorker = new pdfjsLib.PDFWorker({
64
- port: rawWorker as unknown as null
65
- });
66
- pdfjsLib.GlobalWorkerOptions.workerPort = pdfWorker.port;
67
-
68
- return pdfjsLib;
69
- }
70
48
 
71
49
  async function loadPdf(source: PdfSource) {
72
50
  if (!BROWSER || !scrollContainerEl) return;
@@ -75,7 +53,7 @@
75
53
  viewerState.error = null;
76
54
 
77
55
  try {
78
- const pdfjs = await initPdfJs();
56
+ const pdfjs = await getPdfJs();
79
57
  if (!pdfjs) return;
80
58
 
81
59
  const { PDFViewerCore } = await import('./pdf-viewer/PDFViewerCore.js');
@@ -234,17 +212,8 @@
234
212
  viewer = null;
235
213
  }
236
214
  findController = null;
237
-
238
- // Cleanup worker to prevent memory leaks
239
- if (pdfWorker) {
240
- pdfWorker.destroy();
241
- pdfWorker = null;
242
- }
243
- if (rawWorker) {
244
- rawWorker.terminate();
245
- rawWorker = null;
246
- }
247
- pdfjsLib = null;
215
+ // Note: Worker is a global singleton, not cleaned up per-component
216
+ // Use destroyPdfJs() from pdfjs-singleton.js if you need to fully cleanup
248
217
  });
249
218
  </script>
250
219
 
@@ -42,29 +42,6 @@
42
42
  // Core instances (loaded dynamically)
43
43
  let viewer: import('./pdf-viewer/PDFViewerCore.js').PDFViewerCore | null = null;
44
44
  let findController: import('./pdf-viewer/FindController.js').FindController | null = null;
45
- let pdfjsLib: typeof import('pdfjs-dist/legacy/build/pdf.mjs') | null = null;
46
- let pdfWorker: import('pdfjs-dist/legacy/build/pdf.mjs').PDFWorker | null = null;
47
- let rawWorker: Worker | null = null;
48
-
49
- async function initPdfJs() {
50
- if (!BROWSER) return null;
51
-
52
- // Return cached instance if already initialized
53
- if (pdfjsLib && pdfWorker) return pdfjsLib;
54
-
55
- pdfjsLib = await import('pdfjs-dist/legacy/build/pdf.mjs');
56
-
57
- // Create worker only once using import.meta.url
58
- rawWorker = new Worker(new URL('pdfjs-dist/legacy/build/pdf.worker.mjs', import.meta.url), {
59
- type: 'module'
60
- });
61
- pdfWorker = new pdfjsLib.PDFWorker({
62
- port: rawWorker as unknown as null
63
- });
64
- pdfjsLib.GlobalWorkerOptions.workerPort = pdfWorker.port;
65
-
66
- return pdfjsLib;
67
- }
68
45
 
69
46
  async function loadPdf(url: string) {
70
47
  if (!BROWSER || !scrollContainerEl) return;
@@ -73,8 +50,9 @@
73
50
  error = null;
74
51
 
75
52
  try {
76
- // Initialize PDF.js
77
- const pdfjs = await initPdfJs();
53
+ // Get PDF.js from global singleton
54
+ const { getPdfJs } = await import('./pdf-viewer/pdfjs-singleton.js');
55
+ const pdfjs = await getPdfJs();
78
56
  if (!pdfjs) return;
79
57
 
80
58
  // Initialize viewer
@@ -229,17 +207,8 @@
229
207
  viewer = null;
230
208
  }
231
209
  findController = null;
232
-
233
- // Cleanup worker to prevent memory leaks
234
- if (pdfWorker) {
235
- pdfWorker.destroy();
236
- pdfWorker = null;
237
- }
238
- if (rawWorker) {
239
- rawWorker.terminate();
240
- rawWorker = null;
241
- }
242
- pdfjsLib = null;
210
+ // Note: Worker is a global singleton, not cleaned up per-component
211
+ // Use destroyPdfJs() from pdfjs-singleton.js if you need to fully cleanup
243
212
  });
244
213
  </script>
245
214
 
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export { default as PdfViewer, Toolbar as PdfToolbar, Renderer as PdfRenderer } from './PdfViewer.svelte';
2
2
  export type { PdfSource } from './PdfRenderer.svelte';
3
3
  export { getPdfViewerContext, type PdfViewerState, type PdfViewerActions, type PdfViewerContext } from './pdf-viewer/context.js';
4
+ export { destroyPdfJs } from './pdf-viewer/pdfjs-singleton.js';
package/dist/index.js CHANGED
@@ -2,3 +2,5 @@
2
2
  export { default as PdfViewer, Toolbar as PdfToolbar, Renderer as PdfRenderer } from './PdfViewer.svelte';
3
3
  // Export context for custom toolbars
4
4
  export { getPdfViewerContext } from './pdf-viewer/context.js';
5
+ // Export PDF.js singleton utilities
6
+ export { destroyPdfJs } from './pdf-viewer/pdfjs-singleton.js';
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Get the PDF.js library instance. Creates the worker on first call.
3
+ * Subsequent calls return the cached instance.
4
+ */
5
+ export declare function getPdfJs(): Promise<typeof import('pdfjs-dist/legacy/build/pdf.mjs') | null>;
6
+ /**
7
+ * Destroy the PDF.js worker and cleanup resources.
8
+ * Call this when you're completely done with PDF viewing in your app.
9
+ * Note: After calling this, the next getPdfJs() call will create a new worker.
10
+ */
11
+ export declare function destroyPdfJs(): void;
@@ -0,0 +1,51 @@
1
+ import { BROWSER } from 'esm-env';
2
+ // Global singleton state
3
+ let pdfjsLib = null;
4
+ let pdfWorker = null;
5
+ let rawWorker = null;
6
+ let initPromise = null;
7
+ /**
8
+ * Get the PDF.js library instance. Creates the worker on first call.
9
+ * Subsequent calls return the cached instance.
10
+ */
11
+ export async function getPdfJs() {
12
+ if (!BROWSER)
13
+ return null;
14
+ // Return cached instance
15
+ if (pdfjsLib && pdfWorker)
16
+ return pdfjsLib;
17
+ // If initialization is in progress, wait for it
18
+ if (initPromise)
19
+ return initPromise;
20
+ // Start initialization
21
+ initPromise = (async () => {
22
+ pdfjsLib = await import('pdfjs-dist/legacy/build/pdf.mjs');
23
+ // Create worker only once using import.meta.url for proper bundler resolution
24
+ rawWorker = new Worker(new URL('pdfjs-dist/legacy/build/pdf.worker.mjs', import.meta.url), {
25
+ type: 'module'
26
+ });
27
+ pdfWorker = new pdfjsLib.PDFWorker({
28
+ port: rawWorker
29
+ });
30
+ pdfjsLib.GlobalWorkerOptions.workerPort = pdfWorker.port;
31
+ return pdfjsLib;
32
+ })();
33
+ return initPromise;
34
+ }
35
+ /**
36
+ * Destroy the PDF.js worker and cleanup resources.
37
+ * Call this when you're completely done with PDF viewing in your app.
38
+ * Note: After calling this, the next getPdfJs() call will create a new worker.
39
+ */
40
+ export function destroyPdfJs() {
41
+ if (pdfWorker) {
42
+ pdfWorker.destroy();
43
+ pdfWorker = null;
44
+ }
45
+ if (rawWorker) {
46
+ rawWorker.terminate();
47
+ rawWorker = null;
48
+ }
49
+ pdfjsLib = null;
50
+ initPromise = null;
51
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-pdf-view",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "A modern, modular PDF viewer component for Svelte 5. Built on PDF.js with TypeScript support",
5
5
  "author": "Louis Li",
6
6
  "license": "Apache-2.0",