@anaralabs/lector 3.12.2 → 3.12.4

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.
Files changed (2) hide show
  1. package/dist/index.js +68 -14
  2. package/package.json +101 -101
package/dist/index.js CHANGED
@@ -1285,18 +1285,36 @@ var useCanvasLayer = ({ background }) => {
1285
1285
  baseCanvas.style.visibility = "hidden";
1286
1286
  let cancelled = false;
1287
1287
  const viewport = pdfPageProxy.getViewport({ scale: baseScale });
1288
+ const buffer = document.createElement("canvas");
1289
+ buffer.width = baseCanvas.width;
1290
+ buffer.height = baseCanvas.height;
1291
+ const bufferCtx = buffer.getContext("2d");
1292
+ const useBuffer = bufferCtx !== null;
1293
+ const renderCanvas = useBuffer ? buffer : baseCanvas;
1294
+ const renderCtx = bufferCtx ?? context;
1288
1295
  const renderingTask = pdfPageProxy.render({
1289
- canvas: baseCanvas,
1290
- canvasContext: context,
1296
+ canvas: renderCanvas,
1297
+ canvasContext: renderCtx,
1291
1298
  viewport,
1292
1299
  background
1293
1300
  });
1301
+ const releaseBuffer = () => {
1302
+ buffer.width = 0;
1303
+ buffer.height = 0;
1304
+ };
1294
1305
  renderingTask.promise.then(() => {
1295
- if (cancelled) return;
1306
+ if (cancelled) {
1307
+ releaseBuffer();
1308
+ return;
1309
+ }
1310
+ if (useBuffer) {
1311
+ context.clearRect(0, 0, baseCanvas.width, baseCanvas.height);
1312
+ context.drawImage(buffer, 0, 0);
1313
+ }
1296
1314
  baseCanvas.style.visibility = "";
1297
1315
  markPageRendered(pageNumber);
1298
1316
  if (typeof createImageBitmap !== "undefined") {
1299
- createImageBitmap(baseCanvas).then((bitmap) => {
1317
+ createImageBitmap(renderCanvas).then((bitmap) => {
1300
1318
  if (cancelled) {
1301
1319
  bitmap.close();
1302
1320
  return;
@@ -1309,9 +1327,12 @@ var useCanvasLayer = ({ background }) => {
1309
1327
  bitmap
1310
1328
  );
1311
1329
  }).catch(() => {
1312
- });
1330
+ }).finally(releaseBuffer);
1331
+ } else {
1332
+ releaseBuffer();
1313
1333
  }
1314
1334
  }).catch((error) => {
1335
+ releaseBuffer();
1315
1336
  if (cancelled) return;
1316
1337
  if (error?.name === "RenderingCancelledException") return;
1317
1338
  baseCanvas.style.visibility = "";
@@ -3036,18 +3057,32 @@ var useScrollFn = () => {
3036
3057
  );
3037
3058
  return { scrollToFn };
3038
3059
  };
3039
- var useVisiblePage = ({ items }) => {
3060
+ var useVisiblePage = ({
3061
+ items,
3062
+ scrollOffset
3063
+ }) => {
3040
3064
  const zoomLevel = usePdf((state) => state.zoom);
3041
3065
  const isPinching = usePdf((state) => state.isPinching);
3042
3066
  const setCurrentPage = usePdf((state) => state.setCurrentPage);
3043
3067
  const scrollElement = usePdf((state) => state.viewportRef?.current);
3044
3068
  const lastPageRef = useRef(0);
3069
+ const [viewportHeight, setViewportHeight] = useState(0);
3070
+ useEffect(() => {
3071
+ if (!scrollElement) return;
3072
+ const measure = () => setViewportHeight(scrollElement.clientHeight);
3073
+ measure();
3074
+ if (typeof ResizeObserver === "undefined") {
3075
+ window.addEventListener("resize", measure);
3076
+ return () => window.removeEventListener("resize", measure);
3077
+ }
3078
+ const observer = new ResizeObserver(measure);
3079
+ observer.observe(scrollElement);
3080
+ return () => observer.disconnect();
3081
+ }, [scrollElement]);
3045
3082
  const calculateVisiblePageIndex = useCallback(
3046
3083
  (virtualItems) => {
3047
- if (!scrollElement || virtualItems.length === 0) return 0;
3048
- const scrollTop = scrollElement.scrollTop / zoomLevel;
3049
- const viewportHeight = scrollElement.clientHeight / zoomLevel;
3050
- const viewportCenter = scrollTop + viewportHeight / 2;
3084
+ if (virtualItems.length === 0 || scrollOffset == null) return 0;
3085
+ const viewportCenter = scrollOffset + viewportHeight / zoomLevel / 2;
3051
3086
  let closestIndex = 0;
3052
3087
  let smallestDistance = Infinity;
3053
3088
  for (const item of virtualItems) {
@@ -3060,10 +3095,17 @@ var useVisiblePage = ({ items }) => {
3060
3095
  }
3061
3096
  return closestIndex;
3062
3097
  },
3063
- [scrollElement, zoomLevel]
3098
+ [scrollOffset, zoomLevel, viewportHeight]
3064
3099
  );
3065
3100
  useEffect(() => {
3066
- if (!isPinching && items.length > 0) {
3101
+ if (viewportHeight === 0 && scrollElement) {
3102
+ const h = scrollElement.clientHeight;
3103
+ if (h > 0) {
3104
+ setViewportHeight(h);
3105
+ return;
3106
+ }
3107
+ }
3108
+ if (!isPinching && items.length > 0 && viewportHeight > 0 && scrollOffset != null) {
3067
3109
  const mostVisibleIndex = calculateVisiblePageIndex(items);
3068
3110
  const page = mostVisibleIndex + 1;
3069
3111
  if (page !== lastPageRef.current) {
@@ -3071,7 +3113,15 @@ var useVisiblePage = ({ items }) => {
3071
3113
  setCurrentPage?.(page);
3072
3114
  }
3073
3115
  }
3074
- }, [items, isPinching, calculateVisiblePageIndex, setCurrentPage]);
3116
+ }, [
3117
+ items,
3118
+ isPinching,
3119
+ calculateVisiblePageIndex,
3120
+ setCurrentPage,
3121
+ viewportHeight,
3122
+ scrollOffset,
3123
+ scrollElement
3124
+ ]);
3075
3125
  return null;
3076
3126
  };
3077
3127
 
@@ -5267,7 +5317,11 @@ var Pages = ({
5267
5317
  const virtualizerItems = virtualizer?.getVirtualItems() ?? [];
5268
5318
  const items = tempItems.length ? tempItems : virtualizerItems;
5269
5319
  useVisiblePage({
5270
- items
5320
+ items,
5321
+ // Pass through nullish (pre-measure) rather than coercing to 0, so the
5322
+ // hook doesn't publish a top-of-document page before the real offset
5323
+ // (incl. a restored/deep-linked one) arrives.
5324
+ scrollOffset: virtualizer.scrollOffset ?? null
5271
5325
  });
5272
5326
  useFitWidth({ viewportRef: containerRef });
5273
5327
  const largestPageWidth = usePdf(selectLargestPageWidth);
package/package.json CHANGED
@@ -1,103 +1,103 @@
1
1
  {
2
- "name": "@anaralabs/lector",
3
- "version": "3.12.2",
4
- "description": "A headless PDF viewer for React",
5
- "author": "andrewdr (https://github.com/andrewdoro)",
6
- "license": "MIT",
7
- "type": "module",
8
- "sideEffects": false,
9
- "module": "dist/index.js",
10
- "types": "dist/index.d.ts",
11
- "exports": {
12
- ".": {
13
- "types": "./dist/index.d.ts",
14
- "import": "./dist/index.js",
15
- "require": "./esm-only.cjs"
16
- }
17
- },
18
- "files": [
19
- "dist"
20
- ],
21
- "publishConfig": {
22
- "access": "public"
23
- },
24
- "scripts": {
25
- "dev": "tsup --watch --onSuccess 'yalc push'",
26
- "prebuild": "rm -rf dist",
27
- "build": "tsup",
28
- "lint": "biome check .",
29
- "format": "biome format --write .",
30
- "postbuild": "size-limit --json > size.json",
31
- "test": "pnpm run '/^test:/'",
32
- "test:unit": "vitest run",
33
- "test:size": "size-limit",
34
- "prepack": "./scripts/prepack.sh"
35
- },
36
- "devDependencies": {
37
- "@microsoft/api-extractor": "^7.48.1",
38
- "@size-limit/preset-small-lib": "^11.1.6",
39
- "@testing-library/react": "^16.0.0",
40
- "@types/node": "^22.9.0",
41
- "@types/react": "^19.0.1",
42
- "@types/react-dom": "^19.0.2",
43
- "@use-gesture/react": "^10.3.1",
44
- "@vitejs/plugin-react": "^4.3.4",
45
- "@vitest/browser": "^2.0.4",
46
- "clsx": "^2.1.1",
47
- "pdfjs-dist": "^5.5.207",
48
- "playwright": "^1.45.3",
49
- "react": "^19.1.1",
50
- "size-limit": "^11.1.6",
51
- "tsc-alias": "^1.8.10",
52
- "tslib": "^2.6.3",
53
- "tsup": "^8.3.5",
54
- "typescript": "^5.5.3",
55
- "vite": "^5.3.3",
56
- "vitest": "^2.0.4",
57
- "webdriverio": "^8.39.1"
58
- },
59
- "peerDependencies": {
60
- "pdfjs-dist": "^5.5.207",
61
- "react": ">=19"
62
- },
63
- "dependencies": {
64
- "@floating-ui/react": "^0.26.28",
65
- "@radix-ui/react-slot": "^1.1.0",
66
- "@tanstack/react-virtual": "^3.10.9",
67
- "react-dom": "^19.1.1",
68
- "use-debounce": "^10.0.4",
69
- "uuid": "^11.1.0",
70
- "zustand": "^5.0.2"
71
- },
72
- "optionalDependencies": {
73
- "@rollup/rollup-linux-x64-gnu": "^4.28.1"
74
- },
75
- "keywords": [
76
- "pdf",
77
- "react",
78
- "headless",
79
- "viewer",
80
- "react-pdf",
81
- "anaralabs",
82
- "typescript"
83
- ],
84
- "repository": {
85
- "type": "git",
86
- "url": "git+https://github.com/anaralabs/lector.git",
87
- "directory": "packages/lector"
88
- },
89
- "bugs": {
90
- "url": "https://github.com/anaralabs/lector/issues"
91
- },
92
- "homepage": "https://github.com/anaralabs/lector",
93
- "size-limit": [
94
- {
95
- "name": "Client",
96
- "path": "dist/index.js",
97
- "limit": "150 kB",
98
- "ignore": [
99
- "react"
100
- ]
101
- }
102
- ]
2
+ "name": "@anaralabs/lector",
3
+ "version": "3.12.4",
4
+ "description": "A headless PDF viewer for React",
5
+ "author": "andrewdr (https://github.com/andrewdoro)",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "sideEffects": false,
9
+ "module": "dist/index.js",
10
+ "types": "dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js",
15
+ "require": "./esm-only.cjs"
16
+ }
17
+ },
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "scripts": {
25
+ "dev": "tsup --watch --onSuccess 'yalc push'",
26
+ "prebuild": "rm -rf dist",
27
+ "build": "tsup",
28
+ "lint": "biome check .",
29
+ "format": "biome format --write .",
30
+ "postbuild": "size-limit --json > size.json",
31
+ "test": "pnpm run '/^test:/'",
32
+ "test:unit": "vitest run",
33
+ "test:size": "size-limit",
34
+ "prepack": "./scripts/prepack.sh"
35
+ },
36
+ "devDependencies": {
37
+ "@microsoft/api-extractor": "^7.48.1",
38
+ "@size-limit/preset-small-lib": "^11.1.6",
39
+ "@testing-library/react": "^16.0.0",
40
+ "@types/node": "^22.9.0",
41
+ "@types/react": "^19.0.1",
42
+ "@types/react-dom": "^19.0.2",
43
+ "@use-gesture/react": "^10.3.1",
44
+ "@vitejs/plugin-react": "^4.3.4",
45
+ "@vitest/browser": "^3.2.4",
46
+ "clsx": "^2.1.1",
47
+ "pdfjs-dist": "^5.5.207",
48
+ "playwright": "^1.45.3",
49
+ "react": "^19.1.1",
50
+ "size-limit": "^11.1.6",
51
+ "tsc-alias": "^1.8.10",
52
+ "tslib": "^2.6.3",
53
+ "tsup": "^8.3.5",
54
+ "typescript": "^5.5.3",
55
+ "vite": "^6.4.2",
56
+ "vitest": "^3.2.4",
57
+ "webdriverio": "^8.39.1"
58
+ },
59
+ "peerDependencies": {
60
+ "pdfjs-dist": "^5.5.207",
61
+ "react": ">=19"
62
+ },
63
+ "dependencies": {
64
+ "@floating-ui/react": "^0.26.28",
65
+ "@radix-ui/react-slot": "^1.1.0",
66
+ "@tanstack/react-virtual": "^3.10.9",
67
+ "react-dom": "^19.1.1",
68
+ "use-debounce": "^10.0.4",
69
+ "uuid": "^11.1.1",
70
+ "zustand": "^5.0.2"
71
+ },
72
+ "optionalDependencies": {
73
+ "@rollup/rollup-linux-x64-gnu": "^4.28.1"
74
+ },
75
+ "keywords": [
76
+ "pdf",
77
+ "react",
78
+ "headless",
79
+ "viewer",
80
+ "react-pdf",
81
+ "anaralabs",
82
+ "typescript"
83
+ ],
84
+ "repository": {
85
+ "type": "git",
86
+ "url": "git+https://github.com/anaralabs/lector.git",
87
+ "directory": "packages/lector"
88
+ },
89
+ "bugs": {
90
+ "url": "https://github.com/anaralabs/lector/issues"
91
+ },
92
+ "homepage": "https://github.com/anaralabs/lector",
93
+ "size-limit": [
94
+ {
95
+ "name": "Client",
96
+ "path": "dist/index.js",
97
+ "limit": "150 kB",
98
+ "ignore": [
99
+ "react"
100
+ ]
101
+ }
102
+ ]
103
103
  }