@jacktea/pdf-viewer-core 0.1.5

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.
@@ -0,0 +1,1092 @@
1
+ type DocumentSource = {
2
+ type: "url";
3
+ url: string;
4
+ headers?: Record<string, string>;
5
+ } | {
6
+ type: "data";
7
+ data: Uint8Array | ArrayBuffer;
8
+ };
9
+ interface PdfOutlineEntry {
10
+ title?: string;
11
+ dest?: unknown;
12
+ items?: PdfOutlineEntry[];
13
+ }
14
+ type DocumentSourceRef = {
15
+ type: "url";
16
+ url: string;
17
+ } | {
18
+ type: "data";
19
+ };
20
+ declare function toDocumentSourceRef(source: DocumentSource): DocumentSourceRef;
21
+ interface PdfPageHandle {
22
+ getViewport: (params: {
23
+ scale: number;
24
+ rotation?: number;
25
+ }) => {
26
+ width: number;
27
+ height: number;
28
+ };
29
+ rotate?: number;
30
+ }
31
+ interface PdfDocumentHandle {
32
+ numPages: number;
33
+ getPage(pageNumber: number): Promise<PdfPageHandle>;
34
+ getOutline?: () => Promise<PdfOutlineEntry[] | null>;
35
+ getDestination?: (dest: string) => Promise<unknown>;
36
+ getPageIndex?: (ref: unknown) => Promise<number>;
37
+ getMetadata?: () => Promise<unknown>;
38
+ getData?: () => Promise<Uint8Array | ArrayBuffer>;
39
+ destroy?: () => void;
40
+ }
41
+ interface PdfMetadata {
42
+ title?: string;
43
+ author?: string;
44
+ subject?: string;
45
+ keywords?: string;
46
+ creator?: string;
47
+ producer?: string;
48
+ creationDate?: string;
49
+ modDate?: string;
50
+ pdfVersion?: string;
51
+ }
52
+ interface UserInfo {
53
+ id: string;
54
+ name?: string;
55
+ color?: string;
56
+ avatarUrl?: string;
57
+ avatar?: string;
58
+ role?: "admin" | "user" | "viewer" | string;
59
+ }
60
+
61
+ type PdfPasswordRequestReason = "need-password" | "incorrect-password" | "unknown";
62
+ interface PdfLoaderOptions {
63
+ cMapUrl?: string;
64
+ cMapPacked?: boolean;
65
+ standardFontDataUrl?: string;
66
+ wasmUrl?: string;
67
+ password?: string;
68
+ onPasswordRequest?: (reason: PdfPasswordRequestReason) => Promise<string | null> | string | null;
69
+ passwordCancelErrorMessage?: string;
70
+ }
71
+ interface PdfJsGetDocument {
72
+ (source: {
73
+ url?: string;
74
+ data?: Uint8Array | ArrayBuffer;
75
+ httpHeaders?: Record<string, string>;
76
+ cMapUrl?: string;
77
+ cMapPacked?: boolean;
78
+ standardFontDataUrl?: string;
79
+ wasmUrl?: string;
80
+ password?: string;
81
+ }): {
82
+ promise: Promise<PdfDocumentHandle>;
83
+ } | Promise<PdfDocumentHandle>;
84
+ }
85
+ type PdfLoader = (source: DocumentSource) => Promise<PdfDocumentHandle>;
86
+ declare function createPdfLoader(getDocument: PdfJsGetDocument, options?: PdfLoaderOptions | (() => PdfLoaderOptions)): PdfLoader;
87
+
88
+ interface PageMoveResult {
89
+ from: number;
90
+ to: number;
91
+ }
92
+ interface PageDeleteResult {
93
+ visibleIndex: number;
94
+ sourceIndex: number;
95
+ }
96
+ declare class PageManager {
97
+ private order;
98
+ constructor(pageCount: number);
99
+ getPageCount(): number;
100
+ getOrder(): number[];
101
+ deletePage(visibleIndex: number): PageDeleteResult | undefined;
102
+ insertPage(visibleIndex: number, sourceIndex: number): void;
103
+ movePage(fromIndex: number, toIndex: number): PageMoveResult | undefined;
104
+ }
105
+
106
+ declare function exportPdf(sourceData: Uint8Array, pageOrder: number[]): Promise<Uint8Array>;
107
+
108
+ interface OutlineNode {
109
+ title: string;
110
+ pageIndex?: number;
111
+ children: OutlineNode[];
112
+ }
113
+ declare function extractPdfOutline(doc: PdfDocumentHandle): Promise<OutlineNode[]>;
114
+
115
+ interface ThumbnailDescriptor {
116
+ pageIndex: number;
117
+ width: number;
118
+ height: number;
119
+ viewportScale: number;
120
+ rotation: number;
121
+ }
122
+ interface ThumbnailOptions {
123
+ scale?: number;
124
+ }
125
+ declare function extractPdfThumbnails(doc: PdfDocumentHandle, options?: ThumbnailOptions): Promise<ThumbnailDescriptor[]>;
126
+
127
+ interface UndoableCommand {
128
+ execute(): boolean;
129
+ undo(): void;
130
+ }
131
+
132
+ interface NormalizedPoint {
133
+ x: number;
134
+ y: number;
135
+ }
136
+ interface NormalizedRect {
137
+ x: number;
138
+ y: number;
139
+ width: number;
140
+ height: number;
141
+ }
142
+ type AnnotationGeometry = {
143
+ kind: "rect";
144
+ rect: NormalizedRect;
145
+ } | {
146
+ kind: "ellipse";
147
+ rect: NormalizedRect;
148
+ } | {
149
+ kind: "path";
150
+ points: NormalizedPoint[];
151
+ } | {
152
+ kind: "point";
153
+ point: NormalizedPoint;
154
+ };
155
+ declare function clampNormalizedPoint(point: NormalizedPoint): NormalizedPoint;
156
+ declare function clampNormalizedRect(rect: NormalizedRect): NormalizedRect;
157
+
158
+ interface AnnotationStyle {
159
+ strokeColor: string;
160
+ strokeWidth: number;
161
+ fillColor?: string;
162
+ fillOpacity?: number;
163
+ opacity?: number;
164
+ lineCap?: "round" | "butt" | "square";
165
+ lineJoin?: "round" | "miter" | "bevel";
166
+ dash?: "solid" | "dash" | "dot";
167
+ fontSize?: number;
168
+ fontFamily?: string;
169
+ fontWeight?: number | string;
170
+ arrowStyle?: "none" | "standard" | "tapered" | "hollow";
171
+ }
172
+ declare const DEFAULT_ANNOTATION_STYLE: AnnotationStyle;
173
+
174
+ type PermissionAction = "annotation.view" | "annotation.create" | "annotation.update" | "annotation.delete" | "annotation.comment.create" | "comment.view" | "comment.update" | "comment.delete" | "comment.reply" | "thread.resolve" | "thread.reopen";
175
+ type PermissionEffect = "allow" | "deny";
176
+ interface PrincipalInfo {
177
+ userId: string;
178
+ roles: string[];
179
+ }
180
+ interface PolicyRule {
181
+ effect: PermissionEffect;
182
+ actions: PermissionAction[] | "*";
183
+ roles?: string[];
184
+ users?: string[];
185
+ owner?: boolean;
186
+ }
187
+ interface PolicySet {
188
+ rules: PolicyRule[];
189
+ }
190
+ interface ResourcePolicyOverride {
191
+ rules: PolicyRule[];
192
+ }
193
+ interface PermissionContext {
194
+ previewMode: boolean;
195
+ ownerId?: string;
196
+ }
197
+ interface PermissionEvaluationInput {
198
+ action: PermissionAction;
199
+ principal: PrincipalInfo;
200
+ globalPolicy: PolicySet;
201
+ resourcePolicy?: ResourcePolicyOverride;
202
+ context: PermissionContext;
203
+ }
204
+ type PermissionDenyReason = "preview_mode" | "resource_explicit_deny" | "global_explicit_deny" | "no_matching_allow";
205
+ interface PermissionDecision {
206
+ allowed: boolean;
207
+ reason?: PermissionDenyReason;
208
+ source?: "preview" | "resource" | "global" | "default";
209
+ }
210
+ interface AnnotationCapabilities {
211
+ view: boolean;
212
+ update: boolean;
213
+ delete: boolean;
214
+ commentCreate: boolean;
215
+ resolveThread: boolean;
216
+ reopenThread: boolean;
217
+ }
218
+ interface CommentCapabilities {
219
+ view: boolean;
220
+ update: boolean;
221
+ delete: boolean;
222
+ reply: boolean;
223
+ }
224
+ interface DocumentCapabilities {
225
+ annotationCreate: boolean;
226
+ setMode: boolean;
227
+ }
228
+ interface ThreadCapabilities {
229
+ resolve: boolean;
230
+ reopen: boolean;
231
+ }
232
+ type DocumentMode = "normal" | "preview";
233
+
234
+ declare function evaluatePermission(input: PermissionEvaluationInput): PermissionDecision;
235
+
236
+ declare const DEFAULT_PERMISSION_POLICY: PolicySet;
237
+
238
+ type AnnotationType = "highlight" | "underline" | "strike" | "draw" | "rect" | "ellipse" | "text" | "arrow";
239
+ interface AnnotationMetadata {
240
+ authorId?: string;
241
+ authorName?: string;
242
+ createdAt: number;
243
+ updatedAt?: number;
244
+ content?: string;
245
+ code?: string;
246
+ status?: "open" | "resolved";
247
+ acl?: ResourcePolicyOverride;
248
+ }
249
+ interface Annotation {
250
+ id: string;
251
+ pageIndex: number;
252
+ type: AnnotationType;
253
+ geometry: AnnotationGeometry;
254
+ style: AnnotationStyle;
255
+ metadata: AnnotationMetadata;
256
+ capabilities?: AnnotationCapabilities;
257
+ }
258
+
259
+ type AnnotationStoreChangeType = "add" | "update" | "remove" | "replace";
260
+ interface AnnotationStoreChange {
261
+ type: AnnotationStoreChangeType;
262
+ annotation?: Annotation;
263
+ previous?: Annotation;
264
+ annotations: Annotation[];
265
+ }
266
+ type AnnotationStoreListener = (change: AnnotationStoreChange) => void;
267
+ declare class AnnotationStore {
268
+ private annotations;
269
+ private listeners;
270
+ getAll(): Annotation[];
271
+ getById(id: string): Annotation | undefined;
272
+ getByPage(pageIndex: number): Annotation[];
273
+ subscribe(listener: AnnotationStoreListener): () => void;
274
+ replaceAll(annotations: Annotation[]): void;
275
+ applyAdd(annotation: Annotation): boolean;
276
+ applyUpdate(next: Annotation): boolean;
277
+ applyRemove(id: string): Annotation | undefined;
278
+ private emit;
279
+ private updateAnnotationAt;
280
+ }
281
+
282
+ declare class AddAnnotationCommand implements UndoableCommand {
283
+ private store;
284
+ private annotation;
285
+ constructor(store: AnnotationStore, annotation: Annotation);
286
+ execute(): boolean;
287
+ undo(): void;
288
+ }
289
+
290
+ declare class DeletePageCommand implements UndoableCommand {
291
+ private manager;
292
+ private pageIndex;
293
+ private lastDeleted?;
294
+ constructor(manager: PageManager, pageIndex: number);
295
+ execute(): boolean;
296
+ undo(): void;
297
+ }
298
+
299
+ declare class RemoveAnnotationCommand implements UndoableCommand {
300
+ private store;
301
+ private annotationId;
302
+ private removed?;
303
+ constructor(store: AnnotationStore, annotationId: string);
304
+ execute(): boolean;
305
+ undo(): void;
306
+ }
307
+
308
+ declare class ReorderPageCommand implements UndoableCommand {
309
+ private manager;
310
+ private fromIndex;
311
+ private toIndex;
312
+ private lastMove?;
313
+ constructor(manager: PageManager, fromIndex: number, toIndex: number);
314
+ execute(): boolean;
315
+ undo(): void;
316
+ }
317
+
318
+ declare class UpdateAnnotationCommand implements UndoableCommand {
319
+ private store;
320
+ private next;
321
+ private previous?;
322
+ constructor(store: AnnotationStore, next: Annotation);
323
+ execute(): boolean;
324
+ undo(): void;
325
+ }
326
+
327
+ interface UndoManagerOptions {
328
+ /** Maximum number of commands to keep in the undo stack (default: 100) */
329
+ maxStackSize?: number;
330
+ }
331
+ declare class UndoManager {
332
+ private readonly maxStackSize;
333
+ private undoStack;
334
+ private redoStack;
335
+ constructor(options?: UndoManagerOptions);
336
+ execute(command: UndoableCommand): boolean;
337
+ undo(): boolean;
338
+ redo(): boolean;
339
+ canUndo(): boolean;
340
+ canRedo(): boolean;
341
+ reset(): void;
342
+ /** Get the current size of the undo stack */
343
+ getUndoStackSize(): number;
344
+ /** Get the current size of the redo stack */
345
+ getRedoStackSize(): number;
346
+ /** Get the maximum stack size */
347
+ getMaxStackSize(): number;
348
+ }
349
+
350
+ interface CommentContent {
351
+ text: string;
352
+ html?: string;
353
+ imgs?: string[];
354
+ imgRefs?: string[];
355
+ }
356
+ interface AnnotationComment {
357
+ id: string;
358
+ targetAnnotationId: string;
359
+ authorId: string;
360
+ authorName?: string;
361
+ content: CommentContent;
362
+ parentId?: string;
363
+ createdAt: number;
364
+ updatedAt?: number;
365
+ code?: string;
366
+ acl?: ResourcePolicyOverride;
367
+ capabilities?: CommentCapabilities;
368
+ }
369
+
370
+ type CommentThreadStatus = "open" | "resolved";
371
+ interface CommentThread {
372
+ id: string;
373
+ targetAnnotationId: string;
374
+ /**
375
+ * @deprecated Reserved for future use only.
376
+ * Current business status is managed by Annotation.metadata.status.
377
+ */
378
+ status?: CommentThreadStatus;
379
+ comments: AnnotationComment[];
380
+ /**
381
+ * @deprecated Reserved for future use only.
382
+ * Current business status is managed by Annotation.metadata.status.
383
+ */
384
+ capabilities?: ThreadCapabilities;
385
+ }
386
+
387
+ type CommentStoreChangeType = "add" | "update" | "remove" | "replace";
388
+ interface CommentStoreChange {
389
+ type: CommentStoreChangeType;
390
+ thread?: CommentThread;
391
+ comment?: AnnotationComment;
392
+ previous?: AnnotationComment;
393
+ threads: CommentThread[];
394
+ }
395
+ type CommentStoreListener = (change: CommentStoreChange) => void;
396
+ declare class CommentStore {
397
+ private threadsByAnnotation;
398
+ private listeners;
399
+ getThreads(): CommentThread[];
400
+ getThreadByAnnotationId(annotationId: string): CommentThread | undefined;
401
+ subscribe(listener: CommentStoreListener): () => void;
402
+ replaceAll(threads: CommentThread[]): void;
403
+ ensureThread(annotationId: string): CommentThread;
404
+ addComment(comment: AnnotationComment): CommentThread;
405
+ updateComment(next: AnnotationComment): CommentThread | undefined;
406
+ removeComment(annotationId: string, commentId: string): CommentThread | undefined;
407
+ /**
408
+ * @deprecated Reserved for future extension.
409
+ * Thread status is not managed in current business rules.
410
+ */
411
+ resolveThread(annotationId: string): CommentThread | undefined;
412
+ /**
413
+ * @deprecated Reserved for future extension.
414
+ * Thread status is not managed in current business rules.
415
+ */
416
+ reopenThread(annotationId: string): CommentThread | undefined;
417
+ private emit;
418
+ private createThread;
419
+ private cloneThread;
420
+ private addCommentToThread;
421
+ private updateCommentInThread;
422
+ private findCommentById;
423
+ private removeCommentFromThread;
424
+ }
425
+
426
+ type Rotation = 0 | 90 | 180 | 270;
427
+ type ViewerStatus = "idle" | "loading" | "ready" | "error";
428
+ type ScaleMode = "page" | "width" | "actual";
429
+ interface ViewerState {
430
+ page: number;
431
+ pageCount: number;
432
+ pageOrder: number[];
433
+ canUndo: boolean;
434
+ canRedo: boolean;
435
+ scale: number;
436
+ scaleMode: ScaleMode;
437
+ rotation: Rotation;
438
+ status: ViewerStatus;
439
+ outline: OutlineNode[];
440
+ thumbnails: ThumbnailDescriptor[];
441
+ source?: DocumentSourceRef;
442
+ error?: string;
443
+ }
444
+ declare const DEFAULT_VIEWER_STATE: ViewerState;
445
+ declare function clampPage(page: number, pageCount: number): number;
446
+ declare function clampScale(scale: number, minScale: number, maxScale: number): number;
447
+ declare function normalizeRotation(rotation: number): Rotation;
448
+
449
+ type ViewerListener = (state: ViewerState) => void;
450
+
451
+ type TemplatePlaceholderType = "text" | "image";
452
+ interface TemplateStyle {
453
+ rotation: number;
454
+ opacity?: number;
455
+ fontSize?: number;
456
+ fontFamily?: string;
457
+ fontWeight?: number | string;
458
+ fontColor?: string;
459
+ textAlign?: "left" | "center" | "right";
460
+ }
461
+ interface BusinessField {
462
+ key: string;
463
+ label: string;
464
+ type: TemplatePlaceholderType;
465
+ defaultValue?: any;
466
+ }
467
+ interface TemplateElement {
468
+ id: string;
469
+ key: string;
470
+ value: any;
471
+ type: TemplatePlaceholderType;
472
+ pageIndex: number;
473
+ geometry: NormalizedRect;
474
+ style: TemplateStyle;
475
+ renderPolicy: TemplateRenderPolicy;
476
+ }
477
+ interface TemplateRenderPolicy {
478
+ mode: "single" | "all-pages" | "range" | "seam";
479
+ pageRange?: {
480
+ start?: number;
481
+ end?: number;
482
+ };
483
+ seam?: {
484
+ direction: "vertical" | "horizontal";
485
+ align: "center" | "left" | "right";
486
+ overlapRatio?: number;
487
+ };
488
+ }
489
+
490
+ declare class TemplateManager {
491
+ private fields;
492
+ private elements;
493
+ constructor();
494
+ /**
495
+ * Load business schema fields
496
+ */
497
+ loadBusinessSchema(fields: BusinessField[]): void;
498
+ /**
499
+ * Get all available business fields
500
+ */
501
+ getFields(): BusinessField[];
502
+ /**
503
+ * Add a new element to the template
504
+ */
505
+ addElement(element: TemplateElement): void;
506
+ /**
507
+ * Update an existing element
508
+ */
509
+ updateElement(element: TemplateElement): void;
510
+ /**
511
+ * Remove an element by ID
512
+ */
513
+ removeElement(id: string): void;
514
+ /**
515
+ * Get all elements
516
+ */
517
+ getElements(): TemplateElement[];
518
+ /**
519
+ * Get elements for a specific page
520
+ */
521
+ getElementsByPage(pageIndex: number): TemplateElement[];
522
+ /**
523
+ * Get element by ID
524
+ */
525
+ getElement(id: string): TemplateElement | undefined;
526
+ }
527
+
528
+ interface ViewerControllerOptions {
529
+ loader: PdfLoader;
530
+ minScale?: number;
531
+ maxScale?: number;
532
+ zoomStep?: number;
533
+ initialScale?: number;
534
+ initialScaleMode?: ScaleMode;
535
+ initialRotation?: Rotation;
536
+ maxUndoStackSize?: number;
537
+ }
538
+ declare class ViewerController {
539
+ private templateManager;
540
+ private state;
541
+ private listeners;
542
+ private doc?;
543
+ private pageManager?;
544
+ private readonly undoManager;
545
+ private annotationStore;
546
+ private commentStore;
547
+ private loadToken;
548
+ private readonly loader;
549
+ private readonly minScale;
550
+ private readonly maxScale;
551
+ private readonly zoomStep;
552
+ private readonly initialScale;
553
+ private readonly initialRotation;
554
+ constructor(options: ViewerControllerOptions);
555
+ loadDocument(source: DocumentSource): Promise<void>;
556
+ getDocument(): PdfDocumentHandle | undefined;
557
+ getTemplateManager(): TemplateManager;
558
+ setPage(page: number): void;
559
+ zoomIn(): void;
560
+ zoomOut(): void;
561
+ rotate(): void;
562
+ setScale(scale: number): void;
563
+ setRotation(rotation: number): void;
564
+ setScaleMode(scaleMode: ScaleMode): void;
565
+ getState(): ViewerState;
566
+ getAnnotationStore(): AnnotationStore;
567
+ getCommentStore(): CommentStore;
568
+ setAnnotations(annotations: Annotation[]): void;
569
+ setCommentThreads(threads: CommentThread[]): void;
570
+ subscribe(listener: ViewerListener): () => void;
571
+ destroy(): void;
572
+ syncPageManager(options?: {
573
+ preserveOrder?: boolean;
574
+ }): Promise<void>;
575
+ deletePage(pageIndex: number): boolean;
576
+ movePage(fromIndex: number, toIndex: number): boolean;
577
+ undo(): boolean;
578
+ redo(): boolean;
579
+ canUndo(): boolean;
580
+ canRedo(): boolean;
581
+ hasEditableDocumentData(): boolean;
582
+ exportPdf(): Promise<Uint8Array>;
583
+ addAnnotation(annotation: Annotation): boolean;
584
+ updateAnnotation(annotation: Annotation): boolean;
585
+ removeAnnotation(annotationId: string): boolean;
586
+ addComment(comment: AnnotationComment): CommentThread;
587
+ updateComment(comment: AnnotationComment): CommentThread | undefined;
588
+ removeComment(annotationId: string, commentId: string): CommentThread | undefined;
589
+ /**
590
+ * @deprecated Kept for API compatibility.
591
+ * Current business status is managed on annotation metadata.
592
+ */
593
+ resolveCommentThread(annotationId: string): CommentThread | undefined;
594
+ /**
595
+ * @deprecated Kept for API compatibility.
596
+ * Current business status is managed on annotation metadata.
597
+ */
598
+ reopenCommentThread(annotationId: string): CommentThread | undefined;
599
+ private setAnnotationStatus;
600
+ private updateState;
601
+ private applyPageOrderChange;
602
+ private updateUndoState;
603
+ private isValidAnnotationPage;
604
+ private loadSupplemental;
605
+ }
606
+
607
+ /**
608
+ * Position of the watermark on the page
609
+ */
610
+ type WatermarkPosition = "center" | "top-left" | "top-center" | "top-right" | "middle-left" | "middle-right" | "bottom-left" | "bottom-center" | "bottom-right";
611
+ /**
612
+ * Text alignment for multi-line watermarks
613
+ */
614
+ type TextAlign = "left" | "center" | "right";
615
+ /**
616
+ * Base watermark properties shared by all watermark types
617
+ */
618
+ interface BaseWatermark {
619
+ /** Opacity from 0 (transparent) to 1 (opaque) */
620
+ opacity: number;
621
+ /** Rotation in degrees */
622
+ rotation: number;
623
+ /** Position on the page */
624
+ position: WatermarkPosition;
625
+ }
626
+ /**
627
+ * Text watermark configuration
628
+ */
629
+ interface TextWatermark extends BaseWatermark {
630
+ type: "text";
631
+ /** The text content to display (supports multi-line with \n) */
632
+ content: string;
633
+ /** Font size in points */
634
+ fontSize: number;
635
+ /** Color as hex string (e.g., "#808080") */
636
+ color: string;
637
+ /** Text alignment for multi-line content */
638
+ textAlign: TextAlign;
639
+ }
640
+ /**
641
+ * Image watermark configuration
642
+ */
643
+ interface ImageWatermark extends BaseWatermark {
644
+ type: "image";
645
+ /** Image data as Uint8Array (PNG or JPG) */
646
+ imageData: Uint8Array;
647
+ /** Image MIME type */
648
+ mimeType: "image/png" | "image/jpeg";
649
+ /** Scale factor from 0 to 1 */
650
+ scale: number;
651
+ }
652
+ /**
653
+ * Union type for all watermark types
654
+ */
655
+ type Watermark = TextWatermark | ImageWatermark;
656
+ /**
657
+ * Default text watermark settings
658
+ */
659
+ declare const DEFAULT_TEXT_WATERMARK: TextWatermark;
660
+ /**
661
+ * Default image watermark settings (without image data)
662
+ */
663
+ declare const DEFAULT_IMAGE_WATERMARK_SETTINGS: Omit<ImageWatermark, "imageData" | "mimeType">;
664
+ /**
665
+ * Parse hex color to RGB values (0-1 range)
666
+ */
667
+ declare function hexToRgb(hex: string): {
668
+ r: number;
669
+ g: number;
670
+ b: number;
671
+ };
672
+ /**
673
+ * Check if text requires image rendering (non-ASCII chars or multi-line)
674
+ */
675
+ declare function hasNonAsciiChars(text: string): boolean;
676
+
677
+ type ImageMimeType = "image/png" | "image/jpeg";
678
+ interface WatermarkImageUploadResult {
679
+ ref: string;
680
+ url?: string;
681
+ }
682
+ interface WatermarkImageLoadSource {
683
+ ref?: string;
684
+ url?: string;
685
+ mimeType?: ImageMimeType;
686
+ }
687
+ interface WatermarkImageLoadResult {
688
+ data: Uint8Array | ArrayBuffer | Blob;
689
+ mimeType?: ImageMimeType;
690
+ }
691
+ interface WatermarkTransferOptions {
692
+ uploadImage?: (image: {
693
+ data: Uint8Array;
694
+ mimeType: ImageMimeType;
695
+ }) => Promise<WatermarkImageUploadResult | string>;
696
+ loadImage?: (source: WatermarkImageLoadSource) => Promise<WatermarkImageLoadResult | Uint8Array | ArrayBuffer | Blob>;
697
+ }
698
+ interface PdfData {
699
+ version: "1.0";
700
+ meta?: {
701
+ createdAt: number;
702
+ source?: string;
703
+ };
704
+ watermark?: {
705
+ type: "text" | "image";
706
+ opacity: number;
707
+ rotation: number;
708
+ position: "center" | "top-left" | "top-center" | "top-right" | "middle-left" | "middle-right" | "bottom-left" | "bottom-center" | "bottom-right";
709
+ content?: string;
710
+ fontSize?: number;
711
+ color?: string;
712
+ textAlign?: "left" | "center" | "right";
713
+ mimeType?: "image/png" | "image/jpeg";
714
+ imageWidth?: number;
715
+ imageHeight?: number;
716
+ scale?: number;
717
+ imageDataBase64?: string;
718
+ imageRef?: string;
719
+ imageUrl?: string;
720
+ };
721
+ annotations?: Array<Annotation & {
722
+ commentThread?: {
723
+ id: string;
724
+ targetAnnotationId: string;
725
+ /**
726
+ * @deprecated Reserved for future use only.
727
+ * Current business status is managed by Annotation.metadata.status.
728
+ */
729
+ status?: "open" | "resolved";
730
+ comments: Array<{
731
+ id: string;
732
+ authorId: string;
733
+ content: CommentContent;
734
+ parentId?: string;
735
+ createdAt: number;
736
+ updatedAt?: number;
737
+ }>;
738
+ };
739
+ }>;
740
+ templates?: Array<TemplateElement>;
741
+ }
742
+ declare function watermarkToData(watermark: Watermark | null, options?: WatermarkTransferOptions): Promise<PdfData["watermark"] | undefined>;
743
+ declare function dataToWatermark(data: PdfData["watermark"], options?: WatermarkTransferOptions): Promise<Watermark | null>;
744
+ declare function mergeComments(annotations: Annotation[], threads: CommentThread[]): NonNullable<PdfData["annotations"]>;
745
+ declare function extractComments(dataPermissions: NonNullable<PdfData["annotations"]>): {
746
+ annotations: Annotation[];
747
+ threads: CommentThread[];
748
+ };
749
+
750
+ /* tslint:disable */
751
+ /* eslint-disable */
752
+
753
+ /**
754
+ * Embed watermark (Text or Image) into PDF
755
+ *
756
+ * config_json examples:
757
+ * Text: {"type": "text", "content": "Hello", "opacity": 0.5, ...}
758
+ * Image: {"type": "image", "imageDataBase64": "...", ...}
759
+ */
760
+ declare function embed_watermark_wasm(pdf_bytes: Uint8Array, config_json: string): Uint8Array;
761
+
762
+ /**
763
+ * Extract specific pages from PDF
764
+ * page_indices should be a Uint32Array from JS side
765
+ */
766
+ declare function extract_pages_wasm(pdf_bytes: Uint8Array, page_indices: Uint32Array): Uint8Array;
767
+
768
+ /**
769
+ * Get number of pages in PDF
770
+ */
771
+ declare function get_page_count_wasm(pdf_bytes: Uint8Array): number;
772
+
773
+ /**
774
+ * Read PdfData JSON from PDF bytes
775
+ */
776
+ declare function read_pdf_data_wasm(pdf_bytes: Uint8Array): any;
777
+
778
+ /**
779
+ * Write PdfData JSON to PDF bytes
780
+ */
781
+ declare function write_pdf_data_wasm(pdf_bytes: Uint8Array, json_data: string): Uint8Array;
782
+
783
+ declare function loadPdfTools(): Promise<void>;
784
+
785
+ interface PdfToolsModule {
786
+ embed_watermark_wasm: typeof embed_watermark_wasm;
787
+ read_pdf_data_wasm: typeof read_pdf_data_wasm;
788
+ write_pdf_data_wasm: typeof write_pdf_data_wasm;
789
+ extract_pages_wasm: typeof extract_pages_wasm;
790
+ get_page_count_wasm: typeof get_page_count_wasm;
791
+ }
792
+
793
+ type RemoteAnnotationChange = Omit<AnnotationStoreChange, "annotations">;
794
+ type RemoteCommentChange = Omit<CommentStoreChange, "threads">;
795
+ interface SyncState {
796
+ annotations: Annotation[];
797
+ comments: CommentThread[];
798
+ activeUsers: UserInfo[];
799
+ documentMode?: DocumentMode;
800
+ }
801
+ type RemoteChangePayload = {
802
+ type: "annotation";
803
+ change: RemoteAnnotationChange;
804
+ } | {
805
+ type: "comment";
806
+ change: RemoteCommentChange;
807
+ };
808
+ type RemoteInteractionPayload = {
809
+ type: "drag";
810
+ annotationId: string;
811
+ geometry: AnnotationGeometry;
812
+ userId: string;
813
+ } | {
814
+ type: "drag-end";
815
+ annotationId: string;
816
+ userId: string;
817
+ };
818
+ /**
819
+ * Connection status for collaboration providers.
820
+ */
821
+ type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'reconnecting';
822
+ /**
823
+ * Type-safe event handler
824
+ */
825
+ type EventHandler$1<T = unknown> = (payload: T) => void;
826
+ interface CollaborationProvider {
827
+ /**
828
+ * Current connection status.
829
+ */
830
+ readonly status: ConnectionStatus;
831
+ /**
832
+ * Connect to the collaboration session.
833
+ */
834
+ connect(options: {
835
+ documentId: string;
836
+ user: UserInfo;
837
+ }): Promise<void>;
838
+ /**
839
+ * Disconnect from the session.
840
+ */
841
+ disconnect(): void;
842
+ /**
843
+ * Destroy the provider and clean up all resources.
844
+ * Call this when the provider will no longer be used.
845
+ */
846
+ destroy?(): void;
847
+ /**
848
+ * Send a local annotation change to remote peers.
849
+ */
850
+ sendAnnotationChange(change: RemoteAnnotationChange): void;
851
+ /**
852
+ * Send a local comment change to remote peers.
853
+ */
854
+ sendCommentChange(change: RemoteCommentChange): void;
855
+ /**
856
+ * Send an ephemeral interaction event (e.g. drag)
857
+ */
858
+ sendInteraction(payload: RemoteInteractionPayload): void;
859
+ /**
860
+ * Subscribe to remote changes.
861
+ */
862
+ on(event: "remote:change", handler: EventHandler$1<RemoteChangePayload>): void;
863
+ /**
864
+ * Subscribe to remote interactions.
865
+ */
866
+ on(event: "remote:interaction", handler: EventHandler$1<RemoteInteractionPayload>): void;
867
+ /**
868
+ * Subscribe to initial state sync or full re-sync.
869
+ */
870
+ on(event: "sync", handler: EventHandler$1<SyncState>): void;
871
+ /**
872
+ * Subscribe to awareness updates (e.g. who is online).
873
+ */
874
+ on(event: "users:update", handler: EventHandler$1<UserInfo[]>): void;
875
+ /**
876
+ * Subscribe to connection status changes.
877
+ */
878
+ on(event: "status:change", handler: EventHandler$1<ConnectionStatus>): void;
879
+ /**
880
+ * Subscribe to connection errors.
881
+ */
882
+ on(event: "error", handler: EventHandler$1<Error>): void;
883
+ /**
884
+ * Subscribe to collaboration document mode changes.
885
+ */
886
+ on(event: "document:mode:changed", handler: EventHandler$1<DocumentMode>): void;
887
+ /**
888
+ * Set collaboration document mode for the current room.
889
+ */
890
+ setDocumentMode?(mode: DocumentMode): void;
891
+ /**
892
+ * Unsubscribe from events
893
+ */
894
+ off<T = unknown>(event: string, handler: EventHandler$1<T>): void;
895
+ /**
896
+ * Remove all listeners for a specific event
897
+ */
898
+ offAll?(event: string): void;
899
+ /**
900
+ * Remove all event listeners
901
+ */
902
+ removeAllListeners?(): void;
903
+ }
904
+
905
+ declare class UserManager {
906
+ private _currentUser;
907
+ private users;
908
+ constructor(currentUser?: UserInfo);
909
+ get currentUser(): UserInfo | null;
910
+ setCurrentUser(user: UserInfo): void;
911
+ getUser(id: string): UserInfo | undefined;
912
+ updateUsers(users: UserInfo[]): void;
913
+ /**
914
+ * Check if current user can edit/delete an annotation.
915
+ */
916
+ canEditAnnotation(annotation: Annotation): boolean;
917
+ /**
918
+ * Check if current user can edit/delete a comment.
919
+ */
920
+ canEditComment(comment: AnnotationComment): boolean;
921
+ }
922
+
923
+ /**
924
+ * Type-safe event handler for remote interactions
925
+ */
926
+ type InteractionHandler = (payload: RemoteInteractionPayload) => void;
927
+ /**
928
+ * CollaborationManager coordinates real-time collaboration between
929
+ * local state changes and remote peers via a CollaborationProvider.
930
+ */
931
+ declare class CollaborationManager {
932
+ private annotationStore;
933
+ private commentStore;
934
+ private provider;
935
+ private userManager;
936
+ private isApplyingRemote;
937
+ private localUnsubscribers;
938
+ private remoteHandlers;
939
+ private interactionListeners;
940
+ private documentModeListeners;
941
+ private documentMode;
942
+ private isDestroyed;
943
+ constructor(annotationStore: AnnotationStore, commentStore: CommentStore, provider: (CollaborationProvider | null) | undefined, userManager: UserManager);
944
+ /**
945
+ * Set or replace the collaboration provider.
946
+ * Cleans up previous provider listeners before setting new one.
947
+ */
948
+ setProvider(provider: CollaborationProvider): void;
949
+ /**
950
+ * Get the current provider
951
+ */
952
+ getProvider(): CollaborationProvider | null;
953
+ private cleanupLocalListeners;
954
+ private cleanupRemoteListeners;
955
+ /**
956
+ * Connect to a collaboration session for the given document.
957
+ * User must be set via UserManager before connecting.
958
+ */
959
+ connect(documentId: string): Promise<void>;
960
+ /**
961
+ * Disconnect from the current collaboration session.
962
+ */
963
+ disconnect(): void;
964
+ /**
965
+ * Destroy the collaboration manager and clean up all resources.
966
+ * Call this when the manager will no longer be used.
967
+ */
968
+ destroy(): void;
969
+ private setupLocalListeners;
970
+ /**
971
+ * Send an ephemeral interaction event to remote peers.
972
+ */
973
+ sendInteraction(payload: RemoteInteractionPayload): void;
974
+ /**
975
+ * Update collaboration document mode for all participants in current room.
976
+ */
977
+ setDocumentMode(mode: DocumentMode): void;
978
+ /**
979
+ * Get latest known collaboration document mode.
980
+ */
981
+ getDocumentMode(): DocumentMode;
982
+ private setupRemoteListeners;
983
+ private applyRemoteChange;
984
+ private applySyncState;
985
+ private applyDocumentMode;
986
+ private applyRemoteInteraction;
987
+ /**
988
+ * Register a handler for remote interaction events.
989
+ * Returns an unsubscribe function.
990
+ */
991
+ onInteraction(handler: InteractionHandler): () => void;
992
+ /**
993
+ * Remove all interaction listeners.
994
+ */
995
+ clearInteractionListeners(): void;
996
+ /**
997
+ * Register document mode change listener.
998
+ */
999
+ onDocumentModeChange(listener: (mode: DocumentMode) => void): () => void;
1000
+ }
1001
+
1002
+ declare class BroadcastChannelProvider implements CollaborationProvider {
1003
+ private channel;
1004
+ private listeners;
1005
+ private currentUser;
1006
+ private _status;
1007
+ constructor();
1008
+ get status(): ConnectionStatus;
1009
+ private setStatus;
1010
+ connect(options: {
1011
+ documentId: string;
1012
+ user: UserInfo;
1013
+ }): Promise<void>;
1014
+ disconnect(): void;
1015
+ sendAnnotationChange(change: RemoteAnnotationChange): void;
1016
+ sendCommentChange(change: RemoteCommentChange): void;
1017
+ sendInteraction(payload: RemoteInteractionPayload): void;
1018
+ setDocumentMode(mode: DocumentMode): void;
1019
+ on(event: string, handler: Function): void;
1020
+ off(event: string, handler: Function): void;
1021
+ private broadcast;
1022
+ private handleMessage;
1023
+ private emit;
1024
+ }
1025
+
1026
+ /**
1027
+ * Configuration options for WebSocketProvider.
1028
+ */
1029
+ interface WebSocketProviderOptions {
1030
+ /** Enable automatic reconnection (default: true) */
1031
+ reconnection?: boolean;
1032
+ /** Maximum number of reconnection attempts (default: 10) */
1033
+ reconnectionAttempts?: number;
1034
+ /** Initial delay between reconnection attempts in ms (default: 1000) */
1035
+ reconnectionDelay?: number;
1036
+ /** Maximum delay between reconnection attempts in ms (default: 5000) */
1037
+ reconnectionDelayMax?: number;
1038
+ /** Connection timeout in ms (default: 20000) */
1039
+ timeout?: number;
1040
+ /** Optional authentication token for collaboration server */
1041
+ authToken?: string;
1042
+ }
1043
+ /**
1044
+ * Type-safe event handler type
1045
+ */
1046
+ type EventHandler<T = unknown> = (payload: T) => void;
1047
+ declare class WebSocketProvider implements CollaborationProvider {
1048
+ private url;
1049
+ private socket;
1050
+ private listeners;
1051
+ private _status;
1052
+ private pendingMessages;
1053
+ private connectOptions?;
1054
+ private readonly options;
1055
+ private readonly authToken?;
1056
+ private isDestroyed;
1057
+ constructor(url: string, options?: WebSocketProviderOptions);
1058
+ get status(): ConnectionStatus;
1059
+ private setStatus;
1060
+ connect(options: {
1061
+ documentId: string;
1062
+ user: UserInfo;
1063
+ }): Promise<void>;
1064
+ /**
1065
+ * Disconnect from the server and clean up resources
1066
+ */
1067
+ disconnect(): void;
1068
+ /**
1069
+ * Destroy the provider and prevent any further use
1070
+ * Call this when the provider will no longer be used
1071
+ */
1072
+ destroy(): void;
1073
+ sendAnnotationChange(change: RemoteAnnotationChange): void;
1074
+ sendCommentChange(change: RemoteCommentChange): void;
1075
+ sendInteraction(payload: RemoteInteractionPayload): void;
1076
+ setDocumentMode(mode: DocumentMode): void;
1077
+ on<T = unknown>(event: string, handler: EventHandler<T>): void;
1078
+ off<T = unknown>(event: string, handler: EventHandler<T>): void;
1079
+ /**
1080
+ * Remove all listeners for a specific event
1081
+ */
1082
+ offAll(event: string): void;
1083
+ /**
1084
+ * Remove all event listeners
1085
+ */
1086
+ removeAllListeners(): void;
1087
+ private emit;
1088
+ private sendOrQueue;
1089
+ private flushQueue;
1090
+ }
1091
+
1092
+ export { AddAnnotationCommand, type Annotation, type AnnotationCapabilities, type AnnotationComment, type AnnotationGeometry, type AnnotationMetadata, AnnotationStore, type AnnotationStoreChange, type AnnotationStoreListener, type AnnotationStyle, type AnnotationType, type BaseWatermark, BroadcastChannelProvider, type BusinessField, CollaborationManager, type CollaborationProvider, type CommentCapabilities, type CommentContent, CommentStore, type CommentStoreChange, type CommentStoreListener, type CommentThread, type CommentThreadStatus, type ConnectionStatus, DEFAULT_ANNOTATION_STYLE, DEFAULT_IMAGE_WATERMARK_SETTINGS, DEFAULT_PERMISSION_POLICY, DEFAULT_TEXT_WATERMARK, DEFAULT_VIEWER_STATE, DeletePageCommand, type DocumentCapabilities, type DocumentMode, type DocumentSource, type DocumentSourceRef, type ImageWatermark, type NormalizedPoint, type NormalizedRect, type OutlineNode, PageManager, type PdfData, type PdfDocumentHandle, type PdfJsGetDocument, type PdfLoader, type PdfLoaderOptions, type PdfMetadata, type PdfOutlineEntry, type PdfPageHandle, type PdfPasswordRequestReason, type PdfToolsModule, type PermissionAction, type PermissionContext, type PermissionDecision, type PermissionDenyReason, type PermissionEffect, type PermissionEvaluationInput, type PolicyRule, type PolicySet, type PrincipalInfo, type RemoteChangePayload, RemoveAnnotationCommand, ReorderPageCommand, type ResourcePolicyOverride, type Rotation, type ScaleMode, type SyncState, type TemplateElement, TemplateManager, type TemplatePlaceholderType, type TemplateRenderPolicy, type TemplateStyle, type TextAlign, type TextWatermark, type ThreadCapabilities, type ThumbnailDescriptor, UndoManager, type UndoableCommand, UpdateAnnotationCommand, type UserInfo, UserManager, ViewerController, type ViewerListener, type ViewerState, type ViewerStatus, type Watermark, type WatermarkImageLoadResult, type WatermarkImageLoadSource, type WatermarkImageUploadResult, type WatermarkPosition, type WatermarkTransferOptions, WebSocketProvider, type WebSocketProviderOptions, clampNormalizedPoint, clampNormalizedRect, clampPage, clampScale, createPdfLoader, dataToWatermark, embed_watermark_wasm, evaluatePermission, exportPdf, extractComments, extractPdfOutline, extractPdfThumbnails, extract_pages_wasm, get_page_count_wasm, hasNonAsciiChars, hexToRgb, loadPdfTools, mergeComments, normalizeRotation, read_pdf_data_wasm, toDocumentSourceRef, watermarkToData, write_pdf_data_wasm };