@anaralabs/lector 3.14.12 → 3.15.0

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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  **A headless PDF viewer for React.** Compose pages, text selection, search, and annotations into your own reading experience. Lector handles PDF.js rendering and page virtualization; you control the layout and UI.
4
4
 
5
- [Documentation](https://lector-weld.vercel.app/docs) · [Live demo](https://lector-weld.vercel.app) · [npm](https://www.npmjs.com/package/@anaralabs/lector) · [Contributing](https://github.com/anaralabs/lector/blob/main/CONTRIBUTING.md)
5
+ [Documentation](https://anara.com/lector/docs) · [Live demo](https://anara.com/lector) · [npm](https://www.npmjs.com/package/@anaralabs/lector) · [Contributing](https://github.com/anaralabs/lector/blob/main/CONTRIBUTING.md)
6
6
 
7
7
  ## Get a PDF on screen
8
8
 
@@ -46,7 +46,7 @@ export default function PDFViewer() {
46
46
  }
47
47
  ```
48
48
 
49
- For **Next.js**, load the viewer through a Client Component using `dynamic(..., { ssr: false })`; keep PDF.js setup inside the dynamically loaded module. See [installation](https://lector-weld.vercel.app/docs/installation) for the full wrapper, Vite worker setup, and deployments below a path prefix.
49
+ For **Next.js**, load the viewer through a Client Component using `dynamic(..., { ssr: false })`; keep PDF.js setup inside the dynamically loaded module. See [installation](https://anara.com/lector/docs/installation) for the full wrapper, Vite worker setup, and deployments below a path prefix.
50
50
 
51
51
  `Root` loads the document and provides its state. `Pages` owns scrolling and clones one `Page` template for visible pages. `CanvasLayer` paints the PDF; `TextLayer` adds selectable text. Give the viewer a definite height and import the PDF.js stylesheet so its layers align.
52
52
 
@@ -54,23 +54,23 @@ For **Next.js**, load the viewer through a Client Component using `dynamic(...,
54
54
 
55
55
  | Feature | Start here |
56
56
  | --- | --- |
57
- | Toolbar, page input, and layout | [Your first viewer](https://lector-weld.vercel.app/docs/basic-usage) |
58
- | Authenticated URLs, local files, errors, and self-hosted assets | [Loading documents](https://lector-weld.vercel.app/docs/document-loading) |
59
- | Page navigation and fit width | [Navigation](https://lector-weld.vercel.app/docs/code/page-navigation), [zoom](https://lector-weld.vercel.app/docs/code/zoom-control) |
60
- | Page previews | [Thumbnails](https://lector-weld.vercel.app/docs/code/thumbnails) |
61
- | Text search and highlighted results | [Search](https://lector-weld.vercel.app/docs/code/search) |
62
- | Selection and citation regions | [Selection](https://lector-weld.vercel.app/docs/code/select), [highlights](https://lector-weld.vercel.app/docs/code/highlight) |
63
- | PDF links and editable form fields | [Links](https://lector-weld.vercel.app/docs/code/links), [forms](https://lector-weld.vercel.app/docs/code/pdf-form) |
64
- | Dark page rendering | [Dark mode](https://lector-weld.vercel.app/docs/dark-mode) |
65
- | Props, hooks, and defaults | [API reference](https://lector-weld.vercel.app/docs/api) |
66
-
67
- Lector is a toolkit rather than a finished toolbar or a PDF editor. Your app supplies accessible controls, error UI, and storage for user annotations. Search requires embedded text; it does not perform OCR. Custom highlight overlays do not automatically modify the PDF file. See [troubleshooting](https://lector-weld.vercel.app/docs/troubleshooting) for worker errors, blank pages, and layout issues.
57
+ | Toolbar, page input, and layout | [Your first viewer](https://anara.com/lector/docs/basic-usage) |
58
+ | Authenticated URLs, local files, errors, and self-hosted assets | [Loading documents](https://anara.com/lector/docs/document-loading) |
59
+ | Page navigation and fit width | [Navigation](https://anara.com/lector/docs/code/page-navigation), [zoom](https://anara.com/lector/docs/code/zoom-control) |
60
+ | Page previews | [Thumbnails](https://anara.com/lector/docs/code/thumbnails) |
61
+ | Text search and highlighted results | [Search](https://anara.com/lector/docs/code/search) |
62
+ | Selection and citation regions | [Selection](https://anara.com/lector/docs/code/select), [highlights](https://anara.com/lector/docs/code/highlight) |
63
+ | PDF links and editable form fields | [Links](https://anara.com/lector/docs/code/links), [forms](https://anara.com/lector/docs/code/pdf-form) |
64
+ | Dark page rendering | [Dark mode](https://anara.com/lector/docs/dark-mode) |
65
+ | Props, hooks, and defaults | [API reference](https://anara.com/lector/docs/api) |
66
+
67
+ Lector is a toolkit rather than a finished toolbar or a PDF editor. Your app supplies accessible controls, error UI, and storage for user annotations. Search requires embedded text; it does not perform OCR. Custom highlight overlays do not automatically modify the PDF file. See [troubleshooting](https://anara.com/lector/docs/troubleshooting) for worker errors, blank pages, and layout issues.
68
68
 
69
69
  ## Use with a coding assistant
70
70
 
71
- Connect an MCP client to `https://lector-weld.vercel.app/mcp` using Streamable HTTP, with no API key. It can search and read every guide through tools and resources. See [AI agents and MCP](https://lector-weld.vercel.app/docs/agents) for setup and example requests.
71
+ Connect an MCP client to `https://anara.com/lector/mcp` using Streamable HTTP, with no API key. It can search and read every guide through tools and resources. See [AI agents and MCP](https://anara.com/lector/docs/agents) for setup and example requests.
72
72
 
73
- For direct fetching, start with [llms.txt](https://lector-weld.vercel.app/llms.txt), read [individual Markdown guides](https://lector-weld.vercel.app/docs/installation.md), or use the [complete documentation](https://lector-weld.vercel.app/llms-full.txt). These exports are generated from the same source as the website.
73
+ For direct fetching, start with [llms.txt](https://anara.com/lector/llms.txt), read [individual Markdown guides](https://anara.com/lector/docs/installation.md), or use the [complete documentation](https://anara.com/lector/llms-full.txt). These exports are generated from the same source as the website.
74
74
 
75
75
  ## Work on Lector
76
76
 
@@ -9,9 +9,11 @@ import { JSX as JSX_2 } from 'react';
9
9
  import { JSXElementConstructor } from 'react';
10
10
  import { MemoExoticComponent } from 'react';
11
11
  import type { PageViewport } from 'pdfjs-dist';
12
+ import { PageViewport as PageViewport_2 } from 'pdfjs-dist/types/src/display/display_utils';
12
13
  import type { PDFDocumentProxy } from 'pdfjs-dist';
13
14
  import { pdfjsDist } from 'pdfjs-dist';
14
15
  import type { PDFPageProxy } from 'pdfjs-dist';
16
+ import { PDFPageProxy as PDFPageProxy_2 } from 'pdfjs-dist/types/src/display/api';
15
17
  import { default as React_2 } from 'react';
16
18
  import { ReactElement } from 'react';
17
19
  import { ReactNode } from 'react';
@@ -161,6 +163,11 @@ declare interface AnnotationTooltipProps {
161
163
  */
162
164
  export declare function applyContextRecolor(ctx: CanvasRenderingContext2D, map: RenderColorMap, options?: RecolorContextOptions): (finalizeRender?: boolean) => void;
163
165
 
166
+ /** Keep viewport geometry and zoom subscribers in the same coordinate space. */
167
+ export declare function applyViewportZoom(viewport: HTMLDivElement | null, zoom: number): void;
168
+
169
+ declare type ApplyZoom = (zoom: number) => void;
170
+
164
171
  declare interface AsyncSearchOptions extends SearchOptions {
165
172
  /** Cancelling rejects with AbortError and never publishes partial results. */
166
173
  signal?: AbortSignal;
@@ -225,6 +232,14 @@ export declare function computeBaseScale(dpr: number, zoom: number, pageWidth: n
225
232
 
226
233
  export declare function computeTargetScale(dpr: number, zoom: number): number;
227
234
 
235
+ declare type CopyOptions = false | SelectionTextOptions;
236
+
237
+ declare type CopyRegistration = {
238
+ container: HTMLElement;
239
+ options: () => CopyOptions;
240
+ read?: (options: SelectionTextOptions) => string | null | undefined;
241
+ };
242
+
228
243
  /** Reuses two rows across candidate windows and only visits the edit band. */
229
244
  export declare function createBoundedDistance(query: string, maxDistance: number): (text: string, offset: number) => number;
230
245
 
@@ -295,6 +310,13 @@ declare const DEFAULT_DARK_MODE_COLORS: Required<DarkModeColors>;
295
310
  export { DEFAULT_DARK_MODE_COLORS }
296
311
  export { DEFAULT_DARK_MODE_COLORS as DEFAULT_DARK_MODE_COLORS_alias_1 }
297
312
 
313
+ declare type Edit = {
314
+ start: number;
315
+ end: number;
316
+ sourceStart: number;
317
+ sourceEnd: number;
318
+ };
319
+
298
320
  export declare const ensureAnnotationLayerStyles: () => void;
299
321
 
300
322
  export declare const firstMemo: <T>(first: boolean, memo: unknown, initializer: () => T) => T;
@@ -312,6 +334,13 @@ export declare const getFitWidthZoom: (containerWidth: number, viewports: PageVi
312
334
 
313
335
  export declare const getMidHeightOfHighlightLine: (selection: ColoredHighlight) => number;
314
336
 
337
+ /**
338
+ * Read mounted PDF text in DOM/PDF.js order, including explicit line breaks.
339
+ * Null means the selection isn't wholly owned by this viewer or skips pages.
340
+ * Never reorder columns/RTL runs heuristically or silently omit unmounted pages.
341
+ */
342
+ export declare function getPdfSelectionText(selection: Selection | null, container: HTMLElement, options?: SelectionTextOptions): string | null;
343
+
315
344
  /**
316
345
  * Per-text-node client rects for a selection. Avoids the block-level rects
317
346
  * that `range.getClientRects()` returns for `.textLayer` / page wrappers,
@@ -346,6 +375,8 @@ export declare interface HighlightRect_alias_2 {
346
375
  }
347
376
 
348
377
  export declare interface InitialPDFState {
378
+ pageResources?: PageResources;
379
+ initialPage?: number;
349
380
  pdfDocumentProxy: PDFDocumentProxy;
350
381
  pageProxies: PDFPageProxy[];
351
382
  viewports: Array<PageViewport>;
@@ -402,6 +433,26 @@ export declare const mergeTextRuns: <T extends Rect>(rects: T[]) => T[];
402
433
 
403
434
  export declare const NextPage: () => void;
404
435
 
436
+ export declare interface NormalizedText {
437
+ text: string;
438
+ maps: Edit[][];
439
+ }
440
+
441
+ /** Search representation; rendering and copied/source text are never lowercased. */
442
+ export declare function normalizeSearchText(text: string, options?: TextNormalizationOptions, lineBreaks?: readonly number[]): NormalizedText;
443
+
444
+ /** Plain text for quotes/copy. Preserve case, accents, punctuation and paragraphs. */
445
+ export declare function normalizeSelectionText(text: string, options?: SelectionTextOptions): string;
446
+
447
+ /** Expand typographic ligatures without changing mathematical compatibility symbols. */
448
+ export declare function normalizeUnicode(text: string, matchDiacritics?: boolean): string;
449
+
450
+ /** Translate a normalized match back to its complete original glyph span. */
451
+ export declare function originalTextRange(normalized: NormalizedText, start: number, end: number): {
452
+ start: number;
453
+ end: number;
454
+ };
455
+
405
456
  export declare const Outline: ({ children, ...props }: HTMLProps<HTMLUListElement> & {
406
457
  children: ReactElement<typeof OutlineItem>;
407
458
  }) => JSX.Element;
@@ -428,7 +479,42 @@ pageNumber?: number;
428
479
 
429
480
  declare type PageNavigationCallback = (pageNumber: number, explicitDest?: unknown[]) => void;
430
481
 
431
- export declare const Pages: ({ children, gap, virtualizerOptions, initialOffset, onOffsetChange, ...props }: HTMLProps<HTMLDivElement> & {
482
+ /** Owns a document's bounded, deduplicated page acquisition queue. */
483
+ export declare class PageResources {
484
+ private document;
485
+ private rotation;
486
+ private onError;
487
+ private concurrency;
488
+ private pages;
489
+ private requests;
490
+ private queue;
491
+ private active;
492
+ private disposed;
493
+ private listeners;
494
+ private notification;
495
+ private viewports;
496
+ private completePages;
497
+ private viewportUpdates;
498
+ constructor(document: PDFDocumentProxy, firstPage: PDFPageProxy, rotation: number, onError: (error: unknown) => void, concurrency?: number);
499
+ private viewportFor;
500
+ get(pageNumber: number): PDFPageProxy_2 | undefined;
501
+ getSnapshot: () => {
502
+ viewports: PageViewport_2[];
503
+ pageProxies: PDFPageProxy_2[] | undefined;
504
+ };
505
+ subscribe: (listener: () => void) => () => void;
506
+ /** Visible pages move ahead of the background queue; in-flight requests are shared. */
507
+ load: (pageNumber: number) => Promise<PDFPageProxy>;
508
+ private createRequest;
509
+ /** Start after the reader mounts, so unrelated page metadata cannot delay its first render. */
510
+ start: () => void;
511
+ loadAll: () => Promise<PDFPageProxy[]>;
512
+ private pump;
513
+ private notify;
514
+ dispose: () => void;
515
+ }
516
+
517
+ export declare const Pages: ({ children, gap, virtualizerOptions, initialOffset, onOffsetChange, copyOptions, ...props }: HTMLProps<HTMLDivElement> & {
432
518
  virtualizerOptions?: {
433
519
  overscan?: number;
434
520
  };
@@ -436,12 +522,19 @@ export declare const Pages: ({ children, gap, virtualizerOptions, initialOffset,
436
522
  children: ReactElement;
437
523
  initialOffset?: number;
438
524
  onOffsetChange?: (offset: number) => void;
525
+ /** Plain-text PDF copying. Preserve line breaks by default; false uses native copying. */
526
+ copyOptions?: false | SelectionTextOptions;
439
527
  }) => JSX.Element;
440
528
 
441
- declare type PageText = {
529
+ /** Text offsets always address the original, concatenated PDF.js strings. */
530
+ declare interface PageText {
442
531
  pageNumber: number;
443
532
  text: string;
444
- };
533
+ /** Sorted UTF-16 offsets after items with hasEOL, without inserting characters. */
534
+ lineBreaks?: readonly number[];
535
+ }
536
+ export { PageText }
537
+ export { PageText as PageText_alias_1 }
445
538
 
446
539
  export declare interface PdfJsAssetUrls {
447
540
  wasmUrl: string;
@@ -452,7 +545,68 @@ export declare interface PdfJsAssetUrls {
452
545
 
453
546
  export declare const PDFLinkServiceContext: Context<LinkService>;
454
547
 
548
+ /** Document-owned selection; mounted text layers are replaceable projections. */
549
+ export declare class PDFSelectionController {
550
+ private readonly options;
551
+ private snapshot;
552
+ private listeners;
553
+ private layers;
554
+ private pages;
555
+ private container;
556
+ private projection;
557
+ private frame;
558
+ private work;
559
+ private structuralChange;
560
+ private drag;
561
+ private connectedCleanup;
562
+ private generation;
563
+ private keyboardWork;
564
+ private keyboardMoves;
565
+ constructor(options: {
566
+ pageCount: number;
567
+ loadPage: (page: number) => Promise<PDFPageProxy>;
568
+ revealPage?: (page: number) => void;
569
+ });
570
+ getSnapshot: () => PDFTextSelection | null;
571
+ subscribe: (listener: () => void) => () => void;
572
+ get isDragging(): boolean;
573
+ includesPage(page: number): boolean;
574
+ private publish;
575
+ private ordered;
576
+ private bounds;
577
+ private remember;
578
+ private complete;
579
+ setSelection: (anchor: PDFTextAnchor, focus: PDFTextAnchor) => void;
580
+ clear: () => void;
581
+ getText: (options?: SelectionTextOptions) => string | null;
582
+ getSelection: (options?: SelectionTextOptions) => PDFSelectionResult | null;
583
+ getSelectionAsync: (options?: SelectionTextOptions) => Promise<PDFSelectionResult | null>;
584
+ private finishSelection;
585
+ registerLayer(element: HTMLElement, pageNumber: number, width: number, height: number): () => void;
586
+ private anchorFor;
587
+ private capture;
588
+ private schedule;
589
+ private project;
590
+ private hydrate;
591
+ private caret;
592
+ private autoScroll;
593
+ private flushKeyboard;
594
+ connect(container: HTMLElement): () => void;
595
+ }
596
+
597
+ declare interface PDFSelectionResult {
598
+ anchor: PDFTextAnchor;
599
+ focus: PDFTextAnchor;
600
+ text: string;
601
+ highlights: HighlightRect[];
602
+ underlines: HighlightRect[];
603
+ isCollapsed: false;
604
+ }
605
+ export { PDFSelectionResult }
606
+ export { PDFSelectionResult as PDFSelectionResult_alias_1 }
607
+
455
608
  declare interface PDFState {
609
+ selection: PDFSelectionController;
456
610
  pdfDocumentProxy: PDFDocumentProxy;
457
611
  zoom: number;
458
612
  updateZoom: (zoom: number | ((prevZoom: number) => number), isZoomFitWidth?: boolean) => void;
@@ -474,7 +628,14 @@ declare interface PDFState {
474
628
  setVirtualizer: (virtualizer: PDFVirtualizer) => void;
475
629
  highlights: HighlightRect[];
476
630
  setHighlight: (higlights: HighlightRect[]) => void;
631
+ /** Synchronous access; progressive consumers must load an unresolved page first. */
477
632
  getPdfPageProxy: (pageNumber: number) => PDFPageProxy;
633
+ loadPdfPageProxy: (pageNumber: number) => Promise<PDFPageProxy>;
634
+ loadPdfPageProxies: () => Promise<PDFPageProxy[]>;
635
+ isPageLoaded: (pageNumber: number) => boolean;
636
+ /** False until the ordered pageProxies array is complete in progressive mode. */
637
+ pagesLoaded: boolean;
638
+ initialPage: number;
478
639
  customSelectionRects: HighlightRect[];
479
640
  setCustomSelectionRects: (rects: HighlightRect[]) => void;
480
641
  coloredHighlights: ColoredHighlight[];
@@ -502,6 +663,23 @@ export declare const PDFStore: {
502
663
  }) => JSX.Element;
503
664
  };
504
665
 
666
+ /** One-based page and UTF-16 offset in that page's selectable text (BRs excluded). */
667
+ declare interface PDFTextAnchor {
668
+ pageNumber: number;
669
+ offset: number;
670
+ }
671
+ export { PDFTextAnchor }
672
+ export { PDFTextAnchor as PDFTextAnchor_alias_1 }
673
+
674
+ declare interface PDFTextSelection {
675
+ anchor: PDFTextAnchor;
676
+ focus: PDFTextAnchor;
677
+ status: "loading" | "ready" | "error";
678
+ error?: unknown;
679
+ }
680
+ export { PDFTextSelection }
681
+ export { PDFTextSelection as PDFTextSelection_alias_1 }
682
+
505
683
  export declare type PDFVirtualizer = Virtualizer<any, any>;
506
684
 
507
685
  export declare const PreviousPage: () => void;
@@ -525,6 +703,11 @@ declare type Rect = {
525
703
  height: number;
526
704
  };
527
705
 
706
+ /** One copy listener per owner document; no work runs during scroll or render. */
707
+ export declare function registerPdfCopy(container: HTMLElement, options: () => CopyOptions, read?: CopyRegistration["read"]): () => void;
708
+
709
+ export declare function registerViewportZoom(viewport: HTMLDivElement, apply: ApplyZoom): () => void;
710
+
528
711
  /**
529
712
  * Removes any recolor wrapper installed on the context. For long-lived
530
713
  * contexts (the visible canvas in the no-buffer fallback, thumbnails) that
@@ -610,7 +793,7 @@ export declare function searchDocument(pages: SearchPage[], searchText: string,
610
793
 
611
794
  export declare function searchDocumentAsync(pages: SearchPage[], searchText: string, options?: AsyncSearchOptions): Promise<SearchResults>;
612
795
 
613
- declare interface SearchOptions {
796
+ declare interface SearchOptions extends TextNormalizationOptions {
614
797
  threshold?: number;
615
798
  limit?: number;
616
799
  textSize?: number;
@@ -618,10 +801,7 @@ declare interface SearchOptions {
618
801
  export { SearchOptions }
619
802
  export { SearchOptions as SearchOptions_alias_1 }
620
803
 
621
- declare type SearchPage = {
622
- pageNumber: number;
623
- text: string;
624
- };
804
+ declare type SearchPage = PageText;
625
805
 
626
806
  declare interface SearchProps {
627
807
  children: React.ReactNode;
@@ -638,6 +818,8 @@ export declare interface SearchResult {
638
818
  text: string;
639
819
  score: number;
640
820
  matchIndex: number;
821
+ /** Matched UTF-16 span in the original PDF text, when different from searchText.length. */
822
+ matchLength?: number;
641
823
  isExactMatch: boolean;
642
824
  searchText?: string;
643
825
  }
@@ -648,6 +830,41 @@ export declare interface SearchResults {
648
830
  hasMoreResults: boolean;
649
831
  }
650
832
 
833
+ /** A mounted text layer. Only this object owns DOM nodes; snapshots never do. */
834
+ export declare class SelectionPage {
835
+ readonly element: HTMLElement;
836
+ readonly pageNumber: number;
837
+ readonly width: number;
838
+ readonly height: number;
839
+ readonly nodes: {
840
+ node: Text;
841
+ start: number;
842
+ end: number;
843
+ }[];
844
+ readonly content: SelectionPageText;
845
+ constructor(element: HTMLElement, pageNumber: number, width: number, height: number);
846
+ offset(node: Node, offset: number): number | null;
847
+ point(offset: number, end?: boolean): {
848
+ node: Text;
849
+ offset: number;
850
+ } | null;
851
+ rects(from: number, to: number): HighlightRect[];
852
+ }
853
+
854
+ export declare interface SelectionPageText {
855
+ text: string;
856
+ lineBreaks: number[];
857
+ }
858
+
859
+ declare interface SelectionTextOptions {
860
+ /** Preserve line and page breaks by default; space joins single line breaks. */
861
+ lineBreaks?: "preserve" | "space";
862
+ /** Join wrapped words ending in a hard hyphen. Defaults to false. */
863
+ ignoreHyphenation?: boolean;
864
+ }
865
+ export { SelectionTextOptions }
866
+ export { SelectionTextOptions as SelectionTextOptions_alias_1 }
867
+
651
868
  export declare const SelectionTooltip: ({ children }: SelectionTooltipProps) => JSX.Element;
652
869
 
653
870
  declare interface SelectionTooltipProps {
@@ -670,10 +887,7 @@ export declare function sourceSize(source: CanvasImageSource): {
670
887
 
671
888
  export declare const subscribeToViewportInvalidation: (viewport: HTMLDivElement, callback: ViewportCallback) => () => void;
672
889
 
673
- declare type TextContent = {
674
- pageNumber: number;
675
- text: string;
676
- };
890
+ declare type TextContent = PageText;
677
891
 
678
892
  export declare const TextLayer: MemoExoticComponent<({ className, style, ...props }: HTMLProps<HTMLDivElement>) => JSX.Element>;
679
893
 
@@ -682,14 +896,23 @@ declare type TextNodeRect = {
682
896
  element: Element | null;
683
897
  };
684
898
 
899
+ export declare interface TextNormalizationOptions {
900
+ /** Preserve accents by default. False folds Latin, Greek and Cyrillic accents. */
901
+ matchDiacritics?: boolean;
902
+ /** Join letter-hyphen-linebreak-lowercase sequences. Defaults to false. */
903
+ ignoreHyphenation?: boolean;
904
+ }
905
+
685
906
  declare interface TextPosition {
686
907
  pageNumber: number;
687
908
  text: string;
688
909
  matchIndex: number;
910
+ matchLength?: number;
689
911
  searchText?: string;
690
912
  }
691
913
 
692
- export declare const Thumbnail: ({ pageNumber, eager, ...props }: HTMLProps<HTMLCanvasElement> & {
914
+ /** An unresolved page occupies a stable row while its resource is acquired. */
915
+ export declare const Thumbnail: (props: HTMLProps<HTMLCanvasElement> & {
693
916
  pageNumber?: number;
694
917
  eager?: boolean;
695
918
  }) => JSX.Element;
@@ -750,7 +973,7 @@ declare const usePdf: <T>(selector: (state: PDFState) => T) => T;
750
973
  export { usePdf }
751
974
  export { usePdf as usePdf_alias_1 }
752
975
 
753
- export declare const usePDFDocumentContext: ({ onDocumentLoad, onError, source, initialRotation, isZoomFitWidth, zoom, zoomOptions, documentOptions, colorScheme, darkModeColors, }: usePDFDocumentParams) => {
976
+ export declare const usePDFDocumentContext: ({ onDocumentLoad, onError, source, initialRotation, progressive, initialPage, isZoomFitWidth, zoom, zoomOptions, documentOptions, colorScheme, darkModeColors, }: usePDFDocumentParams) => {
754
977
  initialState: InitialPDFState | null | undefined;
755
978
  };
756
979
 
@@ -780,6 +1003,10 @@ export declare interface usePDFDocumentParams {
780
1003
  source: Source;
781
1004
  }) => void;
782
1005
  initialRotation?: number;
1006
+ /** Render the initial page before acquiring the rest. Unloaded page sizes are estimates. */
1007
+ progressive?: boolean;
1008
+ /** One-based page to load and display first. Read when source changes. */
1009
+ initialPage?: number;
783
1010
  isZoomFitWidth?: boolean;
784
1011
  zoom?: number;
785
1012
  zoomOptions?: ZoomOptions;
@@ -831,11 +1058,20 @@ declare const usePDFOutline: () => {
831
1058
 
832
1059
  export declare const usePDFPageNumber: () => number;
833
1060
 
1061
+ /** Selection anchors survive virtualized text-layer removal. */
1062
+ declare function usePdfSelection(): {
1063
+ selection: PDFTextSelection | null;
1064
+ setSelection: (anchor: PDFTextAnchor, focus: PDFTextAnchor) => void;
1065
+ clearSelection: () => void;
1066
+ getText: (options?: SelectionTextOptions) => string | null;
1067
+ getSelection: (options?: SelectionTextOptions) => PDFSelectionResult | null;
1068
+ getSelectionAsync: (options?: SelectionTextOptions) => Promise<PDFSelectionResult | null>;
1069
+ };
1070
+ export { usePdfSelection }
1071
+ export { usePdfSelection as usePdfSelection_alias_1 }
1072
+
834
1073
  export declare const useSearch: () => {
835
- textContent: {
836
- pageNumber: number;
837
- text: string;
838
- }[];
1074
+ textContent: PageText[];
839
1075
  keywords: string[];
840
1076
  searchResults: SearchResults;
841
1077
  search: (searchText: string, options?: SearchOptions) => SearchResults;
@@ -845,22 +1081,26 @@ export declare const useSearch: () => {
845
1081
  };
846
1082
 
847
1083
  export declare const useSelectionDimensions: () => {
848
- getDimension: () => {
1084
+ getDimension: () => PDFSelectionResult | {
849
1085
  highlights: HighlightRect[];
850
1086
  text: string;
851
1087
  isCollapsed: boolean;
852
1088
  } | undefined;
853
1089
  getSelection: () => CollapsibleSelection;
854
- getAnnotationDimension: () => {
1090
+ getAnnotationDimension: () => PDFSelectionResult | {
855
1091
  highlights: HighlightRect[];
856
1092
  underlines: HighlightRect[];
857
1093
  text: string;
858
1094
  isCollapsed: boolean;
859
1095
  } | undefined;
1096
+ getText: (options?: SelectionTextOptions) => string | null;
860
1097
  };
861
1098
 
862
1099
  declare type ViewportCallback = () => void;
863
1100
 
1101
+ /** Materialize one missing selected page as text only, never as a page canvas. */
1102
+ export declare function withSelectionPage<T>(proxy: PDFPageProxy, owner: Document, signal: AbortSignal, read: (page: SelectionPage) => T): Promise<T>;
1103
+
864
1104
  export declare const ZoomIn: ({ ...props }: HTMLProps<HTMLButtonElement>) => JSX.Element;
865
1105
 
866
1106
  export declare interface ZoomOptions {
package/dist/index.d.ts CHANGED
@@ -39,6 +39,7 @@ export { PDFLinkServiceContext } from './_tsup-dts-rollup.js';
39
39
  export { useCreatePDFLinkService } from './_tsup-dts-rollup.js';
40
40
  export { usePDFLinkService } from './_tsup-dts-rollup.js';
41
41
  export { usePDFPageNumber } from './_tsup-dts-rollup.js';
42
+ export { usePdfSelection } from './_tsup-dts-rollup.js';
42
43
  export { useSelectionDimensions } from './_tsup-dts-rollup.js';
43
44
  export { ColoredHighlight } from './_tsup-dts-rollup.js';
44
45
  export { HighlightRect } from './_tsup-dts-rollup.js';
@@ -48,5 +49,10 @@ export { createDarkModeColorMap } from './_tsup-dts-rollup.js';
48
49
  export { DarkModeColors } from './_tsup-dts-rollup.js';
49
50
  export { DEFAULT_DARK_MODE_COLORS } from './_tsup-dts-rollup.js';
50
51
  export { RenderColorMap } from './_tsup-dts-rollup.js';
52
+ export { PDFSelectionResult } from './_tsup-dts-rollup.js';
53
+ export { PDFTextAnchor } from './_tsup-dts-rollup.js';
54
+ export { PDFTextSelection } from './_tsup-dts-rollup.js';
51
55
  export { AsyncSearchOptions } from './_tsup-dts-rollup.js';
52
56
  export { SearchOptions } from './_tsup-dts-rollup.js';
57
+ export { PageText } from './_tsup-dts-rollup.js';
58
+ export { SelectionTextOptions } from './_tsup-dts-rollup.js';