@dtducas/wh-forge-viewer 2.0.0-beta.2 → 3.0.0-beta.1
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 +165 -356
- package/dist/index.d.ts +796 -218
- package/dist/index.esm.js +89348 -45479
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +89369 -45524
- package/dist/index.js.map +1 -1
- package/dist/package.json +7 -0
- package/package.json +11 -1
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Definitions by: Duong Tran Quang <https://github.com/DTDucas>
|
|
4
4
|
/// <reference types="react" />
|
|
5
5
|
declare module '@dtducas/wh-forge-viewer' {
|
|
6
|
-
import type {
|
|
6
|
+
import type { ReactNode } from 'react';
|
|
7
7
|
/**
|
|
8
8
|
* Supported file extensions for the Forge Viewer
|
|
9
9
|
*/
|
|
@@ -68,15 +68,15 @@ declare module '@dtducas/wh-forge-viewer' {
|
|
|
68
68
|
export type TMarkupToolType =
|
|
69
69
|
| 'arrow'
|
|
70
70
|
| 'rectangle'
|
|
71
|
-
| 'ellipse'
|
|
71
|
+
| 'ellipse' // Circle tool
|
|
72
72
|
| 'cloud'
|
|
73
|
-
| 'label'
|
|
73
|
+
| 'label' // Text tool
|
|
74
74
|
| 'freehand' // Pen tool
|
|
75
75
|
| 'line'
|
|
76
76
|
| 'polyline'
|
|
77
77
|
| 'polycloud'
|
|
78
78
|
| 'callout'
|
|
79
|
-
| 'image';
|
|
79
|
+
| 'image'; // Image/Stamp tool
|
|
80
80
|
|
|
81
81
|
/**
|
|
82
82
|
* Markup style configuration
|
|
@@ -264,7 +264,7 @@ declare module '@dtducas/wh-forge-viewer' {
|
|
|
264
264
|
constructor(
|
|
265
265
|
viewer: Autodesk.Viewing.GuiViewer3D,
|
|
266
266
|
eventBus: any,
|
|
267
|
-
config?: IDrawingManagerConfig
|
|
267
|
+
config?: IDrawingManagerConfig,
|
|
268
268
|
);
|
|
269
269
|
enterEditMode(): Promise<void>;
|
|
270
270
|
leaveEditMode(): void;
|
|
@@ -287,26 +287,47 @@ declare module '@dtducas/wh-forge-viewer' {
|
|
|
287
287
|
|
|
288
288
|
// Collaborative Markup API
|
|
289
289
|
getMarkupData(viewableGUID: string): IMarkupDataExport;
|
|
290
|
-
loadMarkupData(
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
290
|
+
loadMarkupData(
|
|
291
|
+
data: IMarkupDataExport,
|
|
292
|
+
options?: ILoadMarkupDataOptions,
|
|
293
|
+
): Promise<void>;
|
|
294
294
|
getMarkupSVG(): string;
|
|
295
295
|
|
|
296
296
|
// Real-time Collaboration Rendering APIs
|
|
297
|
-
renderFromSVG(
|
|
297
|
+
renderFromSVG(
|
|
298
|
+
svgString: string,
|
|
299
|
+
options?: { clearExisting?: boolean; layerId?: string },
|
|
300
|
+
): number;
|
|
298
301
|
mergeFromSVG(svgString: string, layerId?: string): number;
|
|
299
302
|
clearForPageChange(viewableGUID: string): IMarkupDataExport;
|
|
300
|
-
restoreAfterPageChange(
|
|
303
|
+
restoreAfterPageChange(
|
|
304
|
+
data: IMarkupDataExport,
|
|
305
|
+
options?: ILoadMarkupDataOptions,
|
|
306
|
+
): Promise<void>;
|
|
301
307
|
|
|
302
308
|
// SVG/JSON Conversion APIs
|
|
303
309
|
getMarkupDataAsJson(viewableGUID: string): IJsonMarkupData;
|
|
304
|
-
loadMarkupDataFromJson(
|
|
310
|
+
loadMarkupDataFromJson(
|
|
311
|
+
jsonData: IJsonMarkupData,
|
|
312
|
+
options?: ILoadMarkupDataOptions,
|
|
313
|
+
): Promise<void>;
|
|
305
314
|
|
|
306
315
|
// PDF Export API
|
|
307
|
-
exportPDFWithMarkup(
|
|
308
|
-
|
|
309
|
-
|
|
316
|
+
exportPDFWithMarkup(
|
|
317
|
+
pdfSource: Blob | string,
|
|
318
|
+
markupsByPage: IPageMarkupData[],
|
|
319
|
+
options?: IExportPdfOptions,
|
|
320
|
+
): Promise<IExportResult>;
|
|
321
|
+
exportAndDownloadPDF(
|
|
322
|
+
pdfSource: Blob | string,
|
|
323
|
+
markupsByPage: IPageMarkupData[],
|
|
324
|
+
options?: IExportPdfOptions,
|
|
325
|
+
): Promise<boolean>;
|
|
326
|
+
exportCurrentPagePDF(
|
|
327
|
+
pdfSource: Blob | string,
|
|
328
|
+
pageIndex?: number,
|
|
329
|
+
options?: IExportPdfOptions,
|
|
330
|
+
): Promise<IExportResult>;
|
|
310
331
|
|
|
311
332
|
// User Presence API
|
|
312
333
|
updateUserCursor(cursor: IUserCursor): void;
|
|
@@ -392,15 +413,37 @@ declare module '@dtducas/wh-forge-viewer' {
|
|
|
392
413
|
export class PolycloudTool extends MarkupTool {}
|
|
393
414
|
export class CalloutTool extends MarkupTool {}
|
|
394
415
|
export class ImageTool extends MarkupTool {
|
|
395
|
-
setImage(
|
|
396
|
-
|
|
416
|
+
setImage(
|
|
417
|
+
imageData: string,
|
|
418
|
+
width: number,
|
|
419
|
+
height: number,
|
|
420
|
+
type?: 'base64' | 'svg',
|
|
421
|
+
): void;
|
|
422
|
+
getPendingImage(): {
|
|
423
|
+
data: string;
|
|
424
|
+
width: number;
|
|
425
|
+
height: number;
|
|
426
|
+
type: 'base64' | 'svg';
|
|
427
|
+
storageId?: string;
|
|
428
|
+
} | null;
|
|
397
429
|
clearPendingImage(): void;
|
|
398
|
-
loadImageFile(
|
|
430
|
+
loadImageFile(
|
|
431
|
+
file: File,
|
|
432
|
+
options?: { storeInIndexedDB?: boolean },
|
|
433
|
+
): Promise<string | void>;
|
|
399
434
|
loadSVGFile(file: File): Promise<void>;
|
|
400
435
|
// IndexedDB Storage Methods
|
|
401
436
|
initializeStorage(): Promise<void>;
|
|
402
437
|
getStorageService(): ImageStorageService | null;
|
|
403
|
-
storeImage(
|
|
438
|
+
storeImage(
|
|
439
|
+
imageData: string,
|
|
440
|
+
metadata?: {
|
|
441
|
+
fileName?: string;
|
|
442
|
+
mimeType?: string;
|
|
443
|
+
width?: number;
|
|
444
|
+
height?: number;
|
|
445
|
+
},
|
|
446
|
+
): Promise<string>;
|
|
404
447
|
getStoredImage(storageId: string): Promise<string | null>;
|
|
405
448
|
hasStoredImage(storageId: string): Promise<boolean>;
|
|
406
449
|
deleteStoredImage(storageId: string): Promise<boolean>;
|
|
@@ -434,37 +477,6 @@ declare module '@dtducas/wh-forge-viewer' {
|
|
|
434
477
|
// Viewer Component Props
|
|
435
478
|
// ========================================
|
|
436
479
|
|
|
437
|
-
/**
|
|
438
|
-
* Props for ViewerForgePDF component
|
|
439
|
-
*/
|
|
440
|
-
export interface IViewerForgePDFProps {
|
|
441
|
-
/**
|
|
442
|
-
* URL/path to the document to load
|
|
443
|
-
*/
|
|
444
|
-
filePath: string;
|
|
445
|
-
/**
|
|
446
|
-
* File extension (pdf, dwf, dwfx, gltf, glb)
|
|
447
|
-
*/
|
|
448
|
-
fileExt: TSupportedFileExtension;
|
|
449
|
-
/**
|
|
450
|
-
* Toolbar visibility options
|
|
451
|
-
* Controls which toolbar buttons and controls are displayed
|
|
452
|
-
*/
|
|
453
|
-
toolbarOptions?: IToolbarOptions;
|
|
454
|
-
/**
|
|
455
|
-
* Callback to receive viewer instance when initialized
|
|
456
|
-
*/
|
|
457
|
-
setViewer?: (viewer: Autodesk.Viewing.GuiViewer3D | null) => void;
|
|
458
|
-
/**
|
|
459
|
-
* Enable custom markup toolbar
|
|
460
|
-
* @default false
|
|
461
|
-
*/
|
|
462
|
-
enableCustomMarkups?: boolean;
|
|
463
|
-
/**
|
|
464
|
-
* Configuration for DrawingManager
|
|
465
|
-
*/
|
|
466
|
-
markupConfig?: IDrawingManagerConfig;
|
|
467
|
-
}
|
|
468
480
|
/**
|
|
469
481
|
* ViewerForgePDF - React component for displaying PDF and CAD files using Autodesk Forge Viewer
|
|
470
482
|
*
|
|
@@ -543,153 +555,6 @@ declare module '@dtducas/wh-forge-viewer' {
|
|
|
543
555
|
timestamp: number;
|
|
544
556
|
}
|
|
545
557
|
|
|
546
|
-
/**
|
|
547
|
-
* Markup change delta for real-time sync
|
|
548
|
-
*/
|
|
549
|
-
export interface IMarkupDelta {
|
|
550
|
-
type: 'create' | 'update' | 'delete';
|
|
551
|
-
markupId: string;
|
|
552
|
-
data?: Partial<IMarkupItem>;
|
|
553
|
-
timestamp: number;
|
|
554
|
-
/** Compact element for JSON-based sync (attached when using serializer) */
|
|
555
|
-
compactElement?: IMarkupElementCompact;
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
// ========================================
|
|
559
|
-
// JSON-based Sync Types (Compact Format)
|
|
560
|
-
// ========================================
|
|
561
|
-
|
|
562
|
-
/**
|
|
563
|
-
* Compact markup element format for real-time sync
|
|
564
|
-
* ~80 bytes vs ~500 bytes for SVG strings
|
|
565
|
-
*/
|
|
566
|
-
export interface IMarkupElementCompact {
|
|
567
|
-
/** Unique markup ID */
|
|
568
|
-
id: string;
|
|
569
|
-
/** Markup type */
|
|
570
|
-
type: string;
|
|
571
|
-
/** Position in markup coordinates [x, y] */
|
|
572
|
-
pos: [number, number];
|
|
573
|
-
/** Size in markup coordinates [width, height] */
|
|
574
|
-
size: [number, number];
|
|
575
|
-
/** Rotation in radians */
|
|
576
|
-
rot: number;
|
|
577
|
-
/** Style properties (compact keys) */
|
|
578
|
-
style: ICompactStyle;
|
|
579
|
-
/** Shape-specific data */
|
|
580
|
-
shape?: IShapeData;
|
|
581
|
-
/** Version number for CRDT conflict resolution */
|
|
582
|
-
version: number;
|
|
583
|
-
/** Tombstone flag for deletion */
|
|
584
|
-
deleted?: boolean;
|
|
585
|
-
/** Timestamp (Unix epoch ms) */
|
|
586
|
-
ts: number;
|
|
587
|
-
/** Created by user ID */
|
|
588
|
-
createdBy?: string;
|
|
589
|
-
/** Modified by user ID */
|
|
590
|
-
modifiedBy?: string;
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
/**
|
|
594
|
-
* Compact style properties (short keys for minimal payload)
|
|
595
|
-
*/
|
|
596
|
-
export interface ICompactStyle {
|
|
597
|
-
/** Stroke color (hex) */
|
|
598
|
-
sc?: string;
|
|
599
|
-
/** Stroke width */
|
|
600
|
-
sw?: number;
|
|
601
|
-
/** Stroke opacity (0-1) */
|
|
602
|
-
so?: number;
|
|
603
|
-
/** Stroke dash array */
|
|
604
|
-
sd?: string;
|
|
605
|
-
/** Fill color (hex) */
|
|
606
|
-
fc?: string;
|
|
607
|
-
/** Fill opacity (0-1) */
|
|
608
|
-
fo?: number;
|
|
609
|
-
/** Font size */
|
|
610
|
-
fs?: number;
|
|
611
|
-
/** Font family */
|
|
612
|
-
ff?: string;
|
|
613
|
-
/** Font weight */
|
|
614
|
-
fw?: string;
|
|
615
|
-
/** Font style */
|
|
616
|
-
fi?: string;
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
/**
|
|
620
|
-
* Shape-specific data for different markup types
|
|
621
|
-
*/
|
|
622
|
-
export interface IShapeData {
|
|
623
|
-
/** Points array (flat: [x1,y1,x2,y2,...]) */
|
|
624
|
-
points?: number[];
|
|
625
|
-
/** Text content */
|
|
626
|
-
text?: string;
|
|
627
|
-
/** Image data URI */
|
|
628
|
-
imageData?: string;
|
|
629
|
-
/** Cloud arc count */
|
|
630
|
-
arcCount?: number;
|
|
631
|
-
/** Path data string */
|
|
632
|
-
pathData?: string;
|
|
633
|
-
/** Arrow head configuration */
|
|
634
|
-
head?: { type: string; size: number };
|
|
635
|
-
/** Arrow tail configuration */
|
|
636
|
-
tail?: { type: string; size: number };
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
/**
|
|
640
|
-
* Serialize a Forge Markup object to compact JSON format
|
|
641
|
-
*/
|
|
642
|
-
export function serializeMarkup(
|
|
643
|
-
markup: any,
|
|
644
|
-
userId?: string
|
|
645
|
-
): IMarkupElementCompact | null;
|
|
646
|
-
|
|
647
|
-
/**
|
|
648
|
-
* Deserialize compact style to Forge-compatible style object
|
|
649
|
-
*/
|
|
650
|
-
export function deserializeStyle(compact: ICompactStyle): Record<string, any>;
|
|
651
|
-
|
|
652
|
-
/**
|
|
653
|
-
* Expand flat points array to {x, y} objects
|
|
654
|
-
*/
|
|
655
|
-
export function expandPoints(flatPoints: number[]): Array<{ x: number; y: number }>;
|
|
656
|
-
|
|
657
|
-
/**
|
|
658
|
-
* Calculate byte size of serialized markup
|
|
659
|
-
*/
|
|
660
|
-
export function getSerializedSize(compact: IMarkupElementCompact): number;
|
|
661
|
-
|
|
662
|
-
/**
|
|
663
|
-
* Render a compact markup element to the Forge Viewer canvas
|
|
664
|
-
*/
|
|
665
|
-
export function renderMarkupElement(
|
|
666
|
-
element: IMarkupElementCompact,
|
|
667
|
-
markupsCore: any,
|
|
668
|
-
mode?: 'create' | 'update'
|
|
669
|
-
): boolean;
|
|
670
|
-
|
|
671
|
-
/**
|
|
672
|
-
* Delete a markup element from the canvas
|
|
673
|
-
*/
|
|
674
|
-
export function deleteMarkupElement(
|
|
675
|
-
elementId: string,
|
|
676
|
-
markupsCore: any
|
|
677
|
-
): boolean;
|
|
678
|
-
|
|
679
|
-
/**
|
|
680
|
-
* Render multiple markup elements as a batch
|
|
681
|
-
*/
|
|
682
|
-
export function renderMarkupBatch(
|
|
683
|
-
elements: IMarkupElementCompact[],
|
|
684
|
-
markupsCore: any,
|
|
685
|
-
clearExisting?: boolean
|
|
686
|
-
): number;
|
|
687
|
-
|
|
688
|
-
/**
|
|
689
|
-
* Clear all markups from the canvas
|
|
690
|
-
*/
|
|
691
|
-
export function clearAllMarkups(markupsCore: any): void;
|
|
692
|
-
|
|
693
558
|
/**
|
|
694
559
|
* Options for loadMarkupData method
|
|
695
560
|
*/
|
|
@@ -697,11 +562,6 @@ declare module '@dtducas/wh-forge-viewer' {
|
|
|
697
562
|
mode?: 'replace' | 'merge';
|
|
698
563
|
}
|
|
699
564
|
|
|
700
|
-
/**
|
|
701
|
-
* Callback type for markup change subscription
|
|
702
|
-
*/
|
|
703
|
-
export type OnMarkupChangeCallback = (delta: IMarkupDelta) => void;
|
|
704
|
-
|
|
705
565
|
// ========================================
|
|
706
566
|
// User Presence API Types
|
|
707
567
|
// ========================================
|
|
@@ -817,9 +677,21 @@ declare module '@dtducas/wh-forge-viewer' {
|
|
|
817
677
|
*/
|
|
818
678
|
export class MarkupExportService {
|
|
819
679
|
constructor();
|
|
820
|
-
exportPDFWithMarkup(
|
|
821
|
-
|
|
822
|
-
|
|
680
|
+
exportPDFWithMarkup(
|
|
681
|
+
originalPdfBlob: Blob,
|
|
682
|
+
markupsByPage: IPageMarkupData[],
|
|
683
|
+
options?: IExportPdfOptions,
|
|
684
|
+
): Promise<IExportResult>;
|
|
685
|
+
exportPDFWithMarkupMap(
|
|
686
|
+
originalPdfBlob: Blob,
|
|
687
|
+
markupsByPage: Map<number, string>,
|
|
688
|
+
options?: IExportPdfOptions,
|
|
689
|
+
): Promise<IExportResult>;
|
|
690
|
+
exportAndDownload(
|
|
691
|
+
originalPdfBlob: Blob,
|
|
692
|
+
markupsByPage: IPageMarkupData[],
|
|
693
|
+
options?: IExportPdfOptions,
|
|
694
|
+
): Promise<boolean>;
|
|
823
695
|
downloadPdf(blob: Blob, filename?: string): void;
|
|
824
696
|
static fetchPdfBlob(pdfSource: Blob | string): Promise<Blob>;
|
|
825
697
|
}
|
|
@@ -838,7 +710,11 @@ declare module '@dtducas/wh-forge-viewer' {
|
|
|
838
710
|
* ```
|
|
839
711
|
*/
|
|
840
712
|
export class SvgToPdfConverter {
|
|
841
|
-
drawSvgOnPdfPage(
|
|
713
|
+
drawSvgOnPdfPage(
|
|
714
|
+
svgString: string,
|
|
715
|
+
pdfPage: any,
|
|
716
|
+
options: ISvgToPdfOptions,
|
|
717
|
+
): Promise<void>;
|
|
842
718
|
}
|
|
843
719
|
|
|
844
720
|
// ========================================
|
|
@@ -848,7 +724,12 @@ declare module '@dtducas/wh-forge-viewer' {
|
|
|
848
724
|
/**
|
|
849
725
|
* Toolbar button identifiers
|
|
850
726
|
*/
|
|
851
|
-
export type TToolbarButtonId =
|
|
727
|
+
export type TToolbarButtonId =
|
|
728
|
+
| 'pan'
|
|
729
|
+
| 'docBrowser'
|
|
730
|
+
| 'download'
|
|
731
|
+
| 'markup'
|
|
732
|
+
| 'pagination';
|
|
852
733
|
|
|
853
734
|
/**
|
|
854
735
|
* Toolbar button visibility configuration
|
|
@@ -927,7 +808,10 @@ declare module '@dtducas/wh-forge-viewer' {
|
|
|
927
808
|
export class ImageStorageService {
|
|
928
809
|
static getInstance(config?: IImageStorageConfig): ImageStorageService;
|
|
929
810
|
initialize(): Promise<void>;
|
|
930
|
-
storeImage(
|
|
811
|
+
storeImage(
|
|
812
|
+
imageData: string,
|
|
813
|
+
metadata?: Partial<IStoredImage>,
|
|
814
|
+
): Promise<string>;
|
|
931
815
|
getImage(id: string): Promise<IStoredImage | null>;
|
|
932
816
|
hasImage(id: string): Promise<boolean>;
|
|
933
817
|
deleteImage(id: string): Promise<boolean>;
|
|
@@ -945,16 +829,12 @@ declare module '@dtducas/wh-forge-viewer' {
|
|
|
945
829
|
* JSON markup data format for database storage
|
|
946
830
|
* Coordinates are stored as-is (no scaling)
|
|
947
831
|
*/
|
|
832
|
+
/** @deprecated Use canvas-scene/2 (ICanvasMarkupSceneV2) for markup persistence. */
|
|
948
833
|
export interface IJsonMarkupData {
|
|
949
|
-
/** Format version for JSON schema compatibility */
|
|
950
834
|
version: string;
|
|
951
|
-
/** Viewable identifier - provided by the consuming app (any string format) */
|
|
952
835
|
viewableGUID: string;
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
/** Optional metadata for custom data */
|
|
956
|
-
metadata?: Record<string, any>;
|
|
957
|
-
/** Timestamp when data was created (Unix epoch ms) */
|
|
836
|
+
elements: unknown[];
|
|
837
|
+
metadata?: Record<string, unknown>;
|
|
958
838
|
timestamp: number;
|
|
959
839
|
}
|
|
960
840
|
|
|
@@ -1112,13 +992,15 @@ declare module '@dtducas/wh-forge-viewer' {
|
|
|
1112
992
|
*/
|
|
1113
993
|
export function validateMarkupCoordinates(
|
|
1114
994
|
point: IPoint2D,
|
|
1115
|
-
markupsCore: any
|
|
995
|
+
markupsCore: any,
|
|
1116
996
|
): ICoordinateValidationResult;
|
|
1117
997
|
|
|
1118
998
|
/**
|
|
1119
999
|
* Get coordinate space metadata for debugging
|
|
1120
1000
|
*/
|
|
1121
|
-
export function getCoordinateSpaceInfo(
|
|
1001
|
+
export function getCoordinateSpaceInfo(
|
|
1002
|
+
markupsCore: any,
|
|
1003
|
+
): ICoordinateSpaceInfo;
|
|
1122
1004
|
|
|
1123
1005
|
/**
|
|
1124
1006
|
* Convert coordinates between different coordinate spaces
|
|
@@ -1127,11 +1009,707 @@ declare module '@dtducas/wh-forge-viewer' {
|
|
|
1127
1009
|
point: IPoint2D,
|
|
1128
1010
|
from: TCoordinateSpace,
|
|
1129
1011
|
to: TCoordinateSpace,
|
|
1130
|
-
markupsCore: any
|
|
1012
|
+
markupsCore: any,
|
|
1131
1013
|
): IPoint2D;
|
|
1132
1014
|
|
|
1133
1015
|
/**
|
|
1134
1016
|
* Check if the coordinate system is normalized (zoom/pan independent)
|
|
1135
1017
|
*/
|
|
1136
1018
|
export function isCoordinateSystemNormalized(markupsCore: any): boolean;
|
|
1019
|
+
|
|
1020
|
+
// ========================================
|
|
1021
|
+
// Advanced Features (v3.0.0)
|
|
1022
|
+
// ========================================
|
|
1023
|
+
|
|
1024
|
+
// ── Markup Engine Adapter Pattern ──────────────────────────────────────────
|
|
1025
|
+
|
|
1026
|
+
/**
|
|
1027
|
+
* Engine capabilities advertised by each IMarkupEngine implementation.
|
|
1028
|
+
*/
|
|
1029
|
+
export interface IMarkupEngineCapabilities {
|
|
1030
|
+
supportsCollaboration: boolean;
|
|
1031
|
+
supportsBezierArcs: boolean;
|
|
1032
|
+
supportsImages: boolean;
|
|
1033
|
+
supportsExportPDF: boolean;
|
|
1034
|
+
supportsImportSVG: boolean;
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
/**
|
|
1038
|
+
* Serialized engine data payload for persistence (V2: canvas-scene/2 only).
|
|
1039
|
+
*/
|
|
1040
|
+
export interface IMarkupEngineData {
|
|
1041
|
+
format: 'canvas-scene/2';
|
|
1042
|
+
version: string;
|
|
1043
|
+
payload: string;
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
/**
|
|
1047
|
+
* Engine type selector prop value.
|
|
1048
|
+
*/
|
|
1049
|
+
export type TMarkupEngineType = 'canvas';
|
|
1050
|
+
|
|
1051
|
+
/**
|
|
1052
|
+
* Markup engine interface for the canvas-scene/2 engine.
|
|
1053
|
+
*/
|
|
1054
|
+
export interface IMarkupEngine {
|
|
1055
|
+
initialize(): Promise<void>;
|
|
1056
|
+
destroy(): void;
|
|
1057
|
+
activateTool(tool: string): void;
|
|
1058
|
+
deactivateTool(): void;
|
|
1059
|
+
getActiveTool(): string | null;
|
|
1060
|
+
addShape(shape: unknown): void;
|
|
1061
|
+
removeShape(shape: unknown): void;
|
|
1062
|
+
clearLayer(): void;
|
|
1063
|
+
getShapes(): unknown[];
|
|
1064
|
+
undo(): void;
|
|
1065
|
+
redo(): void;
|
|
1066
|
+
getData(): IMarkupEngineData;
|
|
1067
|
+
loadData(data: IMarkupEngineData): void;
|
|
1068
|
+
selectShape(shape: unknown): void;
|
|
1069
|
+
getSelectedShape(): unknown | null;
|
|
1070
|
+
onSelectionChange(cb: (shape: unknown | null) => void): () => void;
|
|
1071
|
+
onShapeAdded(cb: (shape: unknown) => void): () => void;
|
|
1072
|
+
onShapeModified(cb: (shape: unknown) => void): () => void;
|
|
1073
|
+
onShapeRemoved(cb: (shape: unknown) => void): () => void;
|
|
1074
|
+
readonly capabilities: IMarkupEngineCapabilities;
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
// ── Custom Geometry ────────────────────────────────────────────────────────
|
|
1078
|
+
|
|
1079
|
+
/**
|
|
1080
|
+
* Options for SceneBuilderService.createModel().
|
|
1081
|
+
*/
|
|
1082
|
+
export interface ISceneModelOptions {
|
|
1083
|
+
/**
|
|
1084
|
+
* When true, only addGeometry/addMaterial/addFragment can be used.
|
|
1085
|
+
* When false (default), addMesh is also available.
|
|
1086
|
+
*/
|
|
1087
|
+
conserveMemory?: boolean;
|
|
1088
|
+
modelNameOverride?: string;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
/**
|
|
1092
|
+
* Builder API returned by SceneBuilderService.createModel().
|
|
1093
|
+
* Use to add geometry, materials, and fragments to a custom model.
|
|
1094
|
+
*/
|
|
1095
|
+
export interface IModelBuilderAPI {
|
|
1096
|
+
addMaterial(name: string, material: unknown): void;
|
|
1097
|
+
addGeometry(geometry: unknown): number;
|
|
1098
|
+
addFragment(
|
|
1099
|
+
geomIdOrGeom: number | unknown,
|
|
1100
|
+
material: unknown | string,
|
|
1101
|
+
transform: unknown,
|
|
1102
|
+
): number;
|
|
1103
|
+
/** Only available when conserveMemory: false */
|
|
1104
|
+
addMesh(mesh: unknown): boolean;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
/**
|
|
1108
|
+
* Manages viewer.overlays scenes for decoration and transient visuals.
|
|
1109
|
+
*
|
|
1110
|
+
* **Use for:** non-selectable decoration, transient highlights, helper visuals.
|
|
1111
|
+
* **Do NOT use for:** objects requiring selection or dbId interaction.
|
|
1112
|
+
* See SceneBuilderService for those use cases.
|
|
1113
|
+
*
|
|
1114
|
+
* @example
|
|
1115
|
+
* ```typescript
|
|
1116
|
+
* const overlay = new OverlayManager(viewer);
|
|
1117
|
+
* overlay.createScene('highlights');
|
|
1118
|
+
* const sphere = overlay.createSphere(0.5, 0xff0000);
|
|
1119
|
+
* overlay.addMesh(sphere, 'highlights');
|
|
1120
|
+
* ```
|
|
1121
|
+
*/
|
|
1122
|
+
export class OverlayManager {
|
|
1123
|
+
constructor(viewer: Autodesk.Viewing.GuiViewer3D);
|
|
1124
|
+
createScene(name: string): void;
|
|
1125
|
+
removeScene(name: string): void;
|
|
1126
|
+
hasScene(name: string): boolean;
|
|
1127
|
+
clearScene(name: string): void;
|
|
1128
|
+
addMesh(mesh: unknown, sceneName: string): void;
|
|
1129
|
+
removeMesh(mesh: unknown, sceneName: string): void;
|
|
1130
|
+
createSphere(radius: number, color: number): unknown;
|
|
1131
|
+
createBox(
|
|
1132
|
+
width: number,
|
|
1133
|
+
height: number,
|
|
1134
|
+
depth: number,
|
|
1135
|
+
color: number,
|
|
1136
|
+
): unknown;
|
|
1137
|
+
createLine(from: unknown, to: unknown, color: number): unknown;
|
|
1138
|
+
dispose(): void;
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
/**
|
|
1142
|
+
* Creates model-like geometry using Autodesk.Viewing.SceneBuilder.
|
|
1143
|
+
*
|
|
1144
|
+
* **Use for:** objects that need selection, dbId, model aggregate events.
|
|
1145
|
+
* **Do NOT use for:** simple decoration. Use OverlayManager instead.
|
|
1146
|
+
* **Limitations:** no 2D models, no property database, no instance tree.
|
|
1147
|
+
*
|
|
1148
|
+
* @example
|
|
1149
|
+
* ```typescript
|
|
1150
|
+
* const svc = new SceneBuilderService(viewer);
|
|
1151
|
+
* await svc.initialize();
|
|
1152
|
+
* const builder = await svc.createModel();
|
|
1153
|
+
* builder.addMaterial('red', material);
|
|
1154
|
+
* const geomId = builder.addGeometry(geometry);
|
|
1155
|
+
* builder.addFragment(geomId, 'red', transform);
|
|
1156
|
+
* ```
|
|
1157
|
+
*/
|
|
1158
|
+
export class SceneBuilderService {
|
|
1159
|
+
constructor(viewer: Autodesk.Viewing.GuiViewer3D);
|
|
1160
|
+
initialize(): Promise<void>;
|
|
1161
|
+
createModel(options?: ISceneModelOptions): Promise<IModelBuilderAPI>;
|
|
1162
|
+
removeModel(builder: IModelBuilderAPI): void;
|
|
1163
|
+
isInitialized(): boolean;
|
|
1164
|
+
destroy(): void;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
// ── Property Database ──────────────────────────────────────────────────────
|
|
1168
|
+
|
|
1169
|
+
/**
|
|
1170
|
+
* A single resolved property entry from the property database.
|
|
1171
|
+
*/
|
|
1172
|
+
export interface IPropertyEntry {
|
|
1173
|
+
name: string;
|
|
1174
|
+
value: string | number | boolean;
|
|
1175
|
+
category?: string;
|
|
1176
|
+
dataType?: number;
|
|
1177
|
+
units?: string;
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
/**
|
|
1181
|
+
* Attribute definition from the property database.
|
|
1182
|
+
*/
|
|
1183
|
+
export interface IAttributeDef {
|
|
1184
|
+
id: number;
|
|
1185
|
+
name: string;
|
|
1186
|
+
category?: string;
|
|
1187
|
+
dataType?: number;
|
|
1188
|
+
units?: string;
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
/**
|
|
1192
|
+
* Query the Autodesk Forge Viewer property database (runs in web worker).
|
|
1193
|
+
*
|
|
1194
|
+
* ⚠️ `executeQuery` functions run in a web worker. They must be self-contained:
|
|
1195
|
+
* - No external variable references or imports
|
|
1196
|
+
* - No `this` context
|
|
1197
|
+
* - Return value must be JSON-serializable
|
|
1198
|
+
*
|
|
1199
|
+
* @example
|
|
1200
|
+
* ```typescript
|
|
1201
|
+
* const svc = new PropertyDatabaseService(viewer);
|
|
1202
|
+
* const count = await svc.executeQuery(function(pdb) {
|
|
1203
|
+
* var n = 0;
|
|
1204
|
+
* pdb.enumObjects(function() { n++; });
|
|
1205
|
+
* return n;
|
|
1206
|
+
* });
|
|
1207
|
+
* ```
|
|
1208
|
+
*/
|
|
1209
|
+
export class PropertyDatabaseService {
|
|
1210
|
+
constructor(viewer: Autodesk.Viewing.GuiViewer3D);
|
|
1211
|
+
/** Returns false for GLTF/GLB models which have no property database. */
|
|
1212
|
+
isAvailable(): boolean;
|
|
1213
|
+
executeQuery<T>(userFunction: (pdb: unknown) => T): Promise<T>;
|
|
1214
|
+
getObjectProperties(dbId: number): Promise<IPropertyEntry[]>;
|
|
1215
|
+
findObjectsByProperty(
|
|
1216
|
+
propertyName: string,
|
|
1217
|
+
value: string | number | boolean,
|
|
1218
|
+
): Promise<number[]>;
|
|
1219
|
+
getAllAttributes(): Promise<IAttributeDef[]>;
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
// ── Selective Loading ──────────────────────────────────────────────────────
|
|
1223
|
+
|
|
1224
|
+
/**
|
|
1225
|
+
* Axis-aligned bounding box spatial primitive for spatial queries.
|
|
1226
|
+
*/
|
|
1227
|
+
export interface ISpatialPrimitive {
|
|
1228
|
+
aabox: [
|
|
1229
|
+
minX: number,
|
|
1230
|
+
minY: number,
|
|
1231
|
+
minZ: number,
|
|
1232
|
+
maxX: number,
|
|
1233
|
+
maxY: number,
|
|
1234
|
+
maxZ: number,
|
|
1235
|
+
];
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
/**
|
|
1239
|
+
* Spatial query for selective loading.
|
|
1240
|
+
* Only applicable for SVF2 + loadDocumentNode() workflow.
|
|
1241
|
+
*/
|
|
1242
|
+
export interface ISpatialQuery {
|
|
1243
|
+
$intersects?: [ISpatialPrimitive];
|
|
1244
|
+
$encloses?: [ISpatialPrimitive, unknown?, number?];
|
|
1245
|
+
$extent?: [number];
|
|
1246
|
+
$not?: ISpatialQuery;
|
|
1247
|
+
$or?: ISpatialQuery[];
|
|
1248
|
+
$and?: ISpatialQuery[];
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
/**
|
|
1252
|
+
* Property-based query for selective loading.
|
|
1253
|
+
* Keys use '?' prefix for property names.
|
|
1254
|
+
* Example: `{ '?Base Constraint': "'Level 1'" }`
|
|
1255
|
+
*/
|
|
1256
|
+
export interface IPropertyQuery {
|
|
1257
|
+
$or?: IPropertyQuery[];
|
|
1258
|
+
$and?: IPropertyQuery[];
|
|
1259
|
+
$not?: IPropertyQuery;
|
|
1260
|
+
[key: string]: unknown;
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
/**
|
|
1264
|
+
* Load filter for selective loading.
|
|
1265
|
+
*
|
|
1266
|
+
* ⚠️ Only applicable for SVF2 + loadDocumentNode() workflow (cloud-hosted URN models).
|
|
1267
|
+
* Will throw UnsupportedCapabilityError for Local env (PDF/DWF direct file loading).
|
|
1268
|
+
* Check `enhancedViewer.capabilities.selectiveLoading` before using.
|
|
1269
|
+
*/
|
|
1270
|
+
export interface ILoadFilter {
|
|
1271
|
+
spatial_query?: ISpatialQuery;
|
|
1272
|
+
property_query?: IPropertyQuery;
|
|
1273
|
+
root_condition?: 'and' | 'or';
|
|
1274
|
+
/** 'exact' is default but slower; 'immediate' is faster but less precise */
|
|
1275
|
+
spatial_behavior?: 'immediate' | 'exact';
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
// ── Viewer Preset Manager ─────────────────────────────────────────────────
|
|
1279
|
+
|
|
1280
|
+
/**
|
|
1281
|
+
* Built-in viewer preset types.
|
|
1282
|
+
* AEC = Architecture, Engineering, Construction settings.
|
|
1283
|
+
* Navis = Navisworks-compatible settings.
|
|
1284
|
+
*/
|
|
1285
|
+
export type TBuiltinPreset = 'AEC' | 'Navis';
|
|
1286
|
+
|
|
1287
|
+
/**
|
|
1288
|
+
* Viewer settings preset configuration.
|
|
1289
|
+
* Passed to ViewerPresetManager.applyPreset() or as `viewerPreset` prop.
|
|
1290
|
+
*/
|
|
1291
|
+
export interface IViewerPresetSettings {
|
|
1292
|
+
name?: string;
|
|
1293
|
+
settings?: Record<string, boolean | number | string>;
|
|
1294
|
+
extensions?: {
|
|
1295
|
+
load?: string[];
|
|
1296
|
+
unload?: string[];
|
|
1297
|
+
};
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
/**
|
|
1301
|
+
* Manages viewer behavior presets via Autodesk.Viewing.Profile / ProfileSettings.
|
|
1302
|
+
*
|
|
1303
|
+
* **Note:** This is NOT the Autodesk User Profile API. It controls viewer rendering
|
|
1304
|
+
* and behavior settings (ambient shadows, ground reflection, etc.).
|
|
1305
|
+
*
|
|
1306
|
+
* @example
|
|
1307
|
+
* ```typescript
|
|
1308
|
+
* const pm = new ViewerPresetManager(viewer);
|
|
1309
|
+
* pm.applyBuiltinPreset('AEC');
|
|
1310
|
+
* pm.cloneAndApply('AEC', { settings: { ambientShadow: false } });
|
|
1311
|
+
* ```
|
|
1312
|
+
*/
|
|
1313
|
+
export class ViewerPresetManager {
|
|
1314
|
+
constructor(viewer: Autodesk.Viewing.GuiViewer3D);
|
|
1315
|
+
applyPreset(settings: IViewerPresetSettings): void;
|
|
1316
|
+
applyBuiltinPreset(type: TBuiltinPreset): void;
|
|
1317
|
+
cloneAndApply(
|
|
1318
|
+
baseType: TBuiltinPreset,
|
|
1319
|
+
overrides: Partial<IViewerPresetSettings>,
|
|
1320
|
+
): void;
|
|
1321
|
+
registerFileTypePreset(
|
|
1322
|
+
fileType: string,
|
|
1323
|
+
settings: IViewerPresetSettings,
|
|
1324
|
+
): void;
|
|
1325
|
+
resetToDefault(): void;
|
|
1326
|
+
getCurrentPreset(): unknown;
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
// ── Capability Gating ──────────────────────────────────────────────────────
|
|
1330
|
+
|
|
1331
|
+
/**
|
|
1332
|
+
* Capabilities advertised by the enhanced viewer object.
|
|
1333
|
+
* Access via `enhancedViewer.capabilities`.
|
|
1334
|
+
*/
|
|
1335
|
+
export interface IViewerCapabilities {
|
|
1336
|
+
/** true only for SVF2 + loadDocumentNode workflow; false for Local PDF/DWF */
|
|
1337
|
+
selectiveLoading: boolean;
|
|
1338
|
+
/** true when enableSceneBuilder=true and extension loaded successfully */
|
|
1339
|
+
sceneBuilder: boolean;
|
|
1340
|
+
/** true when canvas markup engine is initialized */
|
|
1341
|
+
canvas: boolean;
|
|
1342
|
+
/** true when model has a property database (false for GLTF/GLB) */
|
|
1343
|
+
propertyDatabase: boolean;
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
// ── Markups Panel ─────────────────────────────────────────────────────────
|
|
1347
|
+
|
|
1348
|
+
/** Single markup item displayed in the MarkupsPanel */
|
|
1349
|
+
export interface IMarkupPanelItem {
|
|
1350
|
+
/** Unique entity identifier */
|
|
1351
|
+
id: string;
|
|
1352
|
+
/**
|
|
1353
|
+
* Markup kind — e.g. 'arrow' | 'rectangle' | 'ellipse' | 'polygon' |
|
|
1354
|
+
* 'polyline' | 'line' | 'cloud' | 'polycloud' | 'text' | 'callout' |
|
|
1355
|
+
* 'freehand' | 'highlighter' | 'image'
|
|
1356
|
+
*/
|
|
1357
|
+
kind: string;
|
|
1358
|
+
/** Optional label override; defaults to capitalised kind */
|
|
1359
|
+
title?: string;
|
|
1360
|
+
/** Display name of the creator */
|
|
1361
|
+
authorName?: string;
|
|
1362
|
+
/** Company / organisation of the creator */
|
|
1363
|
+
authorCompany?: string;
|
|
1364
|
+
/** Unix epoch milliseconds */
|
|
1365
|
+
createdAt: number;
|
|
1366
|
+
/** Whether the markup has been published/saved to the server */
|
|
1367
|
+
isPublished?: boolean;
|
|
1368
|
+
/** Override icon stroke colour (default: #ec4a41) */
|
|
1369
|
+
color?: string;
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
// ── User Presence ─────────────────────────────────────────────────────────
|
|
1373
|
+
|
|
1374
|
+
/** Online user presence info for sidebar presence indicator */
|
|
1375
|
+
export interface IUserPresence {
|
|
1376
|
+
userId: string;
|
|
1377
|
+
userName?: string;
|
|
1378
|
+
color: string;
|
|
1379
|
+
isActive: boolean;
|
|
1380
|
+
lastSeen: number;
|
|
1381
|
+
currentPageIndex?: number;
|
|
1382
|
+
avatarUrl?: string;
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
// ── Collab Patch Types ────────────────────────────────────────────────────
|
|
1386
|
+
|
|
1387
|
+
export type TPatchOp = 'create' | 'update' | 'delete';
|
|
1388
|
+
|
|
1389
|
+
export interface ICanvasPatch {
|
|
1390
|
+
op: TPatchOp;
|
|
1391
|
+
shapeId: string;
|
|
1392
|
+
/** Full shape data (omitted for delete) */
|
|
1393
|
+
data?: unknown;
|
|
1394
|
+
/** ISO-8601 timestamp */
|
|
1395
|
+
timestamp: string;
|
|
1396
|
+
actorId: string;
|
|
1397
|
+
version: number;
|
|
1398
|
+
nonce: number;
|
|
1399
|
+
viewableGuid: string;
|
|
1400
|
+
patchId?: string;
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
export interface ICanvasMarkupSceneV2 {
|
|
1404
|
+
format: 'canvas-scene/2';
|
|
1405
|
+
version: '2.0';
|
|
1406
|
+
viewableGuid: string;
|
|
1407
|
+
shapes: unknown[];
|
|
1408
|
+
viewportBounds?: unknown;
|
|
1409
|
+
createdAt: string;
|
|
1410
|
+
updatedAt: string;
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
// ── Collab Adapter ────────────────────────────────────────────────────────
|
|
1414
|
+
|
|
1415
|
+
/** Identifies a collaboration room scoped to a single viewable page. */
|
|
1416
|
+
export interface ICollabRoom {
|
|
1417
|
+
viewableGuid: string;
|
|
1418
|
+
roomId: string;
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
/**
|
|
1422
|
+
* Result of `ICollabAdapter.fetchScene`.
|
|
1423
|
+
* - `mode: 'full'` — full scene replacement; call `api.loadScene(scene)`.
|
|
1424
|
+
* - `mode: 'delta'` — incremental; call `api.applyPatches(deltaPatches)`.
|
|
1425
|
+
*/
|
|
1426
|
+
export interface IFetchSceneResult {
|
|
1427
|
+
mode: 'full' | 'delta';
|
|
1428
|
+
scene: ICanvasMarkupSceneV2 | null;
|
|
1429
|
+
deltaPatches?: ICanvasPatch[];
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
/** Transport-agnostic collab adapter — implement with Socket.IO, WebRTC, etc. */
|
|
1433
|
+
export interface ICollabAdapter {
|
|
1434
|
+
broadcastPatches(patches: ICanvasPatch[], room: ICollabRoom): Promise<void>;
|
|
1435
|
+
fetchScene(room: ICollabRoom): Promise<IFetchSceneResult>;
|
|
1436
|
+
onRemotePatches(room: ICollabRoom, cb: (patches: ICanvasPatch[]) => void): () => void;
|
|
1437
|
+
joinRoom(room: ICollabRoom): void | Promise<void>;
|
|
1438
|
+
leaveRoom(room: ICollabRoom): void | Promise<void>;
|
|
1439
|
+
/** Optional: subscribe to server-initiated full-scene replacements (e.g. version restore). */
|
|
1440
|
+
onRemoteSceneReplace?(room: ICollabRoom, cb: (scene: ICanvasMarkupSceneV2) => void): () => void;
|
|
1441
|
+
/**
|
|
1442
|
+
* Optional: drain the durable outbox for a room.
|
|
1443
|
+
* Called after bootstrap to replay unACKed patches from a previous session.
|
|
1444
|
+
*/
|
|
1445
|
+
drainOutboxForRoom?(room: ICollabRoom): Promise<ICanvasPatch[]>;
|
|
1446
|
+
/** Optional: register a callback fired on transport reconnect for auto re-join. */
|
|
1447
|
+
onReconnect?(cb: () => void): () => void;
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
export type TCollabStatus = 'idle' | 'joining' | 'connected' | 'disconnected' | 'error';
|
|
1451
|
+
|
|
1452
|
+
export interface ICollabStatusEvent {
|
|
1453
|
+
status: TCollabStatus;
|
|
1454
|
+
roomId?: string;
|
|
1455
|
+
error?: Error;
|
|
1456
|
+
}
|
|
1457
|
+
|
|
1458
|
+
// ── Updated ViewerForgePDF Props ──────────────────────────────────────────
|
|
1459
|
+
|
|
1460
|
+
/**
|
|
1461
|
+
* Props for ViewerForgePDF component (v3.0.0)
|
|
1462
|
+
*/
|
|
1463
|
+
export interface IViewerForgePDFProps {
|
|
1464
|
+
/** URL/path to the document to load */
|
|
1465
|
+
filePath: string;
|
|
1466
|
+
/** File extension (pdf, dwf, dwfx, gltf, glb) */
|
|
1467
|
+
fileExt: TSupportedFileExtension;
|
|
1468
|
+
/** Toolbar visibility options */
|
|
1469
|
+
toolbarOptions?: IToolbarOptions;
|
|
1470
|
+
/** Callback to receive enhanced viewer instance when initialized */
|
|
1471
|
+
setViewer?: (viewer: Autodesk.Viewing.GuiViewer3D | null) => void;
|
|
1472
|
+
/** Enable custom markup toolbar (canvas engine). */
|
|
1473
|
+
enableCustomMarkups?: boolean;
|
|
1474
|
+
/** Configuration for DrawingManager. */
|
|
1475
|
+
markupConfig?: IDrawingManagerConfig;
|
|
1476
|
+
/**
|
|
1477
|
+
* Markup engine — only `'canvas'` (canvas-scene/2) is supported.
|
|
1478
|
+
* @default 'canvas' when enableCustomMarkups=true
|
|
1479
|
+
*/
|
|
1480
|
+
markupEngine?: TMarkupEngineType;
|
|
1481
|
+
/**
|
|
1482
|
+
* Enable Autodesk.Viewing.SceneBuilder for model-like custom geometry.
|
|
1483
|
+
* Exposes `enhancedViewer.sceneBuilder` when true.
|
|
1484
|
+
* @default false
|
|
1485
|
+
*/
|
|
1486
|
+
enableSceneBuilder?: boolean;
|
|
1487
|
+
/**
|
|
1488
|
+
* Load filter for selective loading.
|
|
1489
|
+
* ⚠️ Only applicable for SVF2 + loadDocumentNode() workflow.
|
|
1490
|
+
* Has no effect for Local env (PDF/DWF); check `capabilities.selectiveLoading`.
|
|
1491
|
+
*/
|
|
1492
|
+
loadFilter?: ILoadFilter;
|
|
1493
|
+
/** Apply a viewer behavior preset on initialization. */
|
|
1494
|
+
viewerPreset?: IViewerPresetSettings;
|
|
1495
|
+
/**
|
|
1496
|
+
* Online users to display in the sidebar presence indicator.
|
|
1497
|
+
* Pass from your collaboration layer (e.g. WebSocket/Supabase Presence).
|
|
1498
|
+
* @default []
|
|
1499
|
+
*/
|
|
1500
|
+
onlineUsers?: IUserPresence[];
|
|
1501
|
+
/**
|
|
1502
|
+
* Markup items to display in the Markups side panel.
|
|
1503
|
+
* Build from your collaborative state (IMarkupElementCompact → IMarkupPanelItem).
|
|
1504
|
+
* @default []
|
|
1505
|
+
*/
|
|
1506
|
+
markupItems?: IMarkupPanelItem[];
|
|
1507
|
+
/** Called when user clicks a markup row in the Markups panel. */
|
|
1508
|
+
onMarkupItemClick?: (id: string) => void;
|
|
1509
|
+
/**
|
|
1510
|
+
* Called when a shape is selected or deselected on the canvas.
|
|
1511
|
+
* Receives the shape `entityId` on selection, or `null` on deselect / toolbar close.
|
|
1512
|
+
* Use this to look up per-shape metadata (author, timestamps) from your state store
|
|
1513
|
+
* and pass it back via `selectedShapeInfo`.
|
|
1514
|
+
*/
|
|
1515
|
+
onShapeSelect?: (entityId: string | null) => void;
|
|
1516
|
+
/**
|
|
1517
|
+
* Metadata to display in the Markup Edit Drawer history section for the
|
|
1518
|
+
* currently selected shape. All fields are pre-formatted display strings so
|
|
1519
|
+
* the library stays format-agnostic.
|
|
1520
|
+
*
|
|
1521
|
+
* When `historyEntries` is provided it takes priority over `createdBy`/`updatedBy`
|
|
1522
|
+
* and renders the full timeline (newest-first, as ordered by the host app).
|
|
1523
|
+
* @example
|
|
1524
|
+
* selectedShapeInfo={{
|
|
1525
|
+
* historyEntries: [
|
|
1526
|
+
* 'Edited by Bob on 31 Mar 2026, 01:28',
|
|
1527
|
+
* 'Created by Alice on 17 Mar 2026, 09:40',
|
|
1528
|
+
* ],
|
|
1529
|
+
* }}
|
|
1530
|
+
* @example
|
|
1531
|
+
* // Legacy fallback (still supported)
|
|
1532
|
+
* selectedShapeInfo={{
|
|
1533
|
+
* createdBy: 'Created by Alice on 17 Mar 2026, 09:40',
|
|
1534
|
+
* updatedBy: 'Updated by Bob on 18 Mar 2026, 11:20',
|
|
1535
|
+
* }}
|
|
1536
|
+
*/
|
|
1537
|
+
selectedShapeInfo?: {
|
|
1538
|
+
createdBy?: string;
|
|
1539
|
+
updatedBy?: string;
|
|
1540
|
+
/**
|
|
1541
|
+
* Full history timeline for the selected shape, newest-first.
|
|
1542
|
+
* Each entry is a pre-formatted string (e.g. 'Edited by Bob on 31 Mar 2026, 01:28').
|
|
1543
|
+
* When present, supersedes `createdBy`/`updatedBy`.
|
|
1544
|
+
*/
|
|
1545
|
+
historyEntries?: string[];
|
|
1546
|
+
};
|
|
1547
|
+
/**
|
|
1548
|
+
* Enable canvas markup debug logger.
|
|
1549
|
+
* Logs shape lifecycle, selection, property changes, history, and scene operations
|
|
1550
|
+
* to the browser console. Exposes `window.__WH_MARKUP_DEBUG__` helpers at runtime.
|
|
1551
|
+
* @default false
|
|
1552
|
+
*/
|
|
1553
|
+
enableMarkupDebug?: boolean;
|
|
1554
|
+
/** Load the Autodesk.BIM360.Minimap extension — shows a floating 2D minimap panel. Default: false */
|
|
1555
|
+
enableMinimap?: boolean;
|
|
1556
|
+
// ── Collaborative Markup ────────────────────────────────────────────────
|
|
1557
|
+
/**
|
|
1558
|
+
* Transport adapter for real-time collaborative markup.
|
|
1559
|
+
* Implement `ICollabAdapter` using Socket.IO, WebRTC, or any transport.
|
|
1560
|
+
* When provided (with `collabActorId` and `collabDrawingId`), the library
|
|
1561
|
+
* creates a `CanvasCollabSessionService` internally and manages room lifecycle.
|
|
1562
|
+
* If omitted, markup runs in offline mode.
|
|
1563
|
+
*/
|
|
1564
|
+
collabAdapter?: ICollabAdapter;
|
|
1565
|
+
/**
|
|
1566
|
+
* Current user's actor ID for LWW conflict resolution and echo prevention.
|
|
1567
|
+
* Required when `collabAdapter` is provided.
|
|
1568
|
+
*/
|
|
1569
|
+
collabActorId?: string;
|
|
1570
|
+
/**
|
|
1571
|
+
* Drawing/document identifier used to construct room IDs.
|
|
1572
|
+
* Room ID format: `${collabDrawingId}:${viewableGuid}`
|
|
1573
|
+
* Required when `collabAdapter` is provided.
|
|
1574
|
+
*/
|
|
1575
|
+
collabDrawingId?: string;
|
|
1576
|
+
/**
|
|
1577
|
+
* Canonical viewable GUID from the host app (e.g. from `/pages` endpoint).
|
|
1578
|
+
* When provided, the library immediately joins the collab room for this page.
|
|
1579
|
+
* Changes to this prop trigger a room re-join. If null/undefined, collab stays idle.
|
|
1580
|
+
*/
|
|
1581
|
+
collabViewableGuid?: string | null;
|
|
1582
|
+
/**
|
|
1583
|
+
* Called when collaborative session status changes.
|
|
1584
|
+
* @param evt - Status event with status, optional roomId, optional error
|
|
1585
|
+
*/
|
|
1586
|
+
onCollabStatusChange?: (evt: ICollabStatusEvent) => void;
|
|
1587
|
+
/**
|
|
1588
|
+
* Called when a collaborative session error occurs.
|
|
1589
|
+
*/
|
|
1590
|
+
onCollabError?: (error: Error) => void;
|
|
1591
|
+
|
|
1592
|
+
// ── Export with Markup ──────────────────────────────────────────────────
|
|
1593
|
+
/**
|
|
1594
|
+
* Optional override for the page list used during export.
|
|
1595
|
+
*
|
|
1596
|
+
* When provided, these GUIDs are passed to `fetchAllScenesForExport` instead of
|
|
1597
|
+
* the Forge runtime GUIDs — eliminating the namespace mismatch that occurs when
|
|
1598
|
+
* the BE persists scenes by canonical page UUIDs (different from Forge page GUIDs).
|
|
1599
|
+
*
|
|
1600
|
+
* Should return the same ordered page list you received from the `/pages` registration
|
|
1601
|
+
* endpoint, mapped by `pageIndex`.
|
|
1602
|
+
*
|
|
1603
|
+
* @example
|
|
1604
|
+
* ```tsx
|
|
1605
|
+
* getExportViewablePages={() =>
|
|
1606
|
+
* pagesRef.current.map(p => ({ pageIndex: p.pageIndex, viewableGuid: p.viewableGUID }))
|
|
1607
|
+
* }
|
|
1608
|
+
* ```
|
|
1609
|
+
*/
|
|
1610
|
+
getExportViewablePages?: () => Array<{ pageIndex: number; viewableGuid: string }>;
|
|
1611
|
+
|
|
1612
|
+
/**
|
|
1613
|
+
* Async callback to fetch canvas-scene/2 data for ALL pages from the server
|
|
1614
|
+
* before merging markup into the exported PDF.
|
|
1615
|
+
*
|
|
1616
|
+
* Input: Array of every viewable GUID in the document.
|
|
1617
|
+
* Output: Record mapping each GUID to its scene or `null` (no markup on that page).
|
|
1618
|
+
*
|
|
1619
|
+
* Rules enforced by the library:
|
|
1620
|
+
* - Every GUID in the input must appear as a key in the output; missing keys throw.
|
|
1621
|
+
* - Non-null scenes must have `format === 'canvas-scene/2'` and `viewableGuid` matching the key.
|
|
1622
|
+
* - If all scenes are null/empty → original PDF is downloaded unchanged.
|
|
1623
|
+
* - If this prop is omitted → "Export with Markup" is a no-op (logs a warning).
|
|
1624
|
+
*
|
|
1625
|
+
* @example
|
|
1626
|
+
* ```tsx
|
|
1627
|
+
* fetchAllScenesForExport={async (guids) => {
|
|
1628
|
+
* const res = await api.getMarkupScenes({ viewableGuids: guids });
|
|
1629
|
+
* // res: { [guid]: ICanvasMarkupSceneV2 | null }
|
|
1630
|
+
* return res;
|
|
1631
|
+
* }}
|
|
1632
|
+
* ```
|
|
1633
|
+
*/
|
|
1634
|
+
fetchAllScenesForExport?: (
|
|
1635
|
+
viewableGuids: string[],
|
|
1636
|
+
) => Promise<Record<string, ICanvasMarkupSceneV2 | null>>;
|
|
1637
|
+
|
|
1638
|
+
/**
|
|
1639
|
+
* Called at key points in the export lifecycle.
|
|
1640
|
+
* Use this to show loading spinners, progress indicators, and error toasts.
|
|
1641
|
+
*
|
|
1642
|
+
* @example
|
|
1643
|
+
* ```tsx
|
|
1644
|
+
* onExportStatus={(evt) => {
|
|
1645
|
+
* if (evt.status === 'start') setExporting(true);
|
|
1646
|
+
* if (evt.status === 'success') setExporting(false);
|
|
1647
|
+
* if (evt.status === 'error') { setExporting(false); toast.error(evt.error?.message); }
|
|
1648
|
+
* }}
|
|
1649
|
+
* ```
|
|
1650
|
+
*/
|
|
1651
|
+
onExportStatus?: (event: IExportStatusEvent) => void;
|
|
1652
|
+
|
|
1653
|
+
/**
|
|
1654
|
+
* Optional TTF font configuration for text export.
|
|
1655
|
+
*
|
|
1656
|
+
* Override when the default NotoSans TTF URLs are blocked by a CSP or network
|
|
1657
|
+
* policy. Must point to valid `.ttf`/`.otf` files — WOFF2 causes invisible text
|
|
1658
|
+
* in pdf-lib and should not be used.
|
|
1659
|
+
*
|
|
1660
|
+
* If omitted, the library fetches NotoSans TTF from Google Fonts CDN with an
|
|
1661
|
+
* 8 s timeout, falling back to Helvetica (Latin-only) on failure.
|
|
1662
|
+
*
|
|
1663
|
+
* @example
|
|
1664
|
+
* ```tsx
|
|
1665
|
+
* <ViewerForgePDF
|
|
1666
|
+
* exportFontConfig={{
|
|
1667
|
+
* fontUrls: ['https://my-cdn.example.com/fonts/noto-sans.ttf'],
|
|
1668
|
+
* fetchTimeoutMs: 5000,
|
|
1669
|
+
* }}
|
|
1670
|
+
* />
|
|
1671
|
+
* ```
|
|
1672
|
+
*/
|
|
1673
|
+
exportFontConfig?: IExportFontConfig;
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
/**
|
|
1677
|
+
* Font configuration for PDF text export.
|
|
1678
|
+
* Controls which TTF font file(s) are used when rendering text markups into PDF.
|
|
1679
|
+
*/
|
|
1680
|
+
export interface IExportFontConfig {
|
|
1681
|
+
/**
|
|
1682
|
+
* Ordered list of TTF/OTF font URLs to try (primary first, then fallbacks).
|
|
1683
|
+
* WOFF2 is not supported — only TTF/OTF files are accepted.
|
|
1684
|
+
* @default NotoSans Regular from Google Fonts CDN
|
|
1685
|
+
*/
|
|
1686
|
+
fontUrls?: string[];
|
|
1687
|
+
/**
|
|
1688
|
+
* Per-URL fetch timeout in milliseconds.
|
|
1689
|
+
* @default 8000
|
|
1690
|
+
*/
|
|
1691
|
+
fetchTimeoutMs?: number;
|
|
1692
|
+
}
|
|
1693
|
+
|
|
1694
|
+
/**
|
|
1695
|
+
* Export lifecycle event emitted by the canvas export pipeline.
|
|
1696
|
+
*/
|
|
1697
|
+
export interface IExportStatusEvent {
|
|
1698
|
+
/** Current stage of the export. */
|
|
1699
|
+
status: 'start' | 'success' | 'error';
|
|
1700
|
+
/** Present only when `status === 'error'`. */
|
|
1701
|
+
error?: Error;
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
/**
|
|
1705
|
+
* Canvas-scene/2 markup scene for a single page.
|
|
1706
|
+
* Used as the element type in the `fetchAllScenesForExport` return value.
|
|
1707
|
+
*/
|
|
1708
|
+
export interface ICanvasMarkupSceneV2 {
|
|
1709
|
+
format: 'canvas-scene/2';
|
|
1710
|
+
viewableGuid: string;
|
|
1711
|
+
shapes: unknown[];
|
|
1712
|
+
viewportBounds?: { x: number; y: number; width: number; height: number };
|
|
1713
|
+
[key: string]: unknown;
|
|
1714
|
+
}
|
|
1137
1715
|
}
|