@extend-ai/react-pptx 0.1.1 → 0.2.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/CHANGELOG.md CHANGED
@@ -8,6 +8,12 @@
8
8
 
9
9
  ## Unreleased
10
10
 
11
+ - Add a cold-start `createPptxThumbnailRenderer` API with package-owned PNG, canvas, ImageBitmap,
12
+ and SVG outputs, explicit thumbnail font policy, cancellation, bounded concurrency, shared
13
+ presentation assets, and phase-level performance measurements.
14
+ - Make slide navigation observable before off-window rendering completes, isolate resource
15
+ readiness per slide mount, update zoom and fit geometry without rebuilding mounted slide DOM,
16
+ and reduce thumbnail work outside the visible rail.
11
17
  - Expose consumer-owned slide thumbnail rails through `usePptxViewerThumbnails`, including stable
12
18
  container refs, resolution bounds, render status, imperative rendering, and cleanup. Add
13
19
  DOCX-style visible/prefetch render windows and virtualize the built-in thumbnail scrollport.
package/README.md CHANGED
@@ -150,6 +150,49 @@ return (
150
150
  `usePptxViewer` exposes the reactive navigation/search/zoom controller. `onViewportReady`
151
151
  provides the internal slide surface for advanced integrations and test harnesses.
152
152
 
153
+ ## Cold-start thumbnails
154
+
155
+ `createPptxThumbnailRenderer` renders directly from a `ParsedPresentation`; it does not mount or
156
+ initialize `ReactPptxViewer`. One renderer reuses its font manager, DOM/SVG rendering context, and
157
+ presentation asset cache across slide requests. The parsed presentation can later be passed to
158
+ `ReactPptxViewer` without fetching or parsing it again.
159
+
160
+ ```ts
161
+ import { createPptxThumbnailRenderer, parsePresentation } from '@extend-ai/react-pptx';
162
+
163
+ const presentation = await parsePresentation(source, {
164
+ onPerformanceMeasurement: recordMeasurement,
165
+ });
166
+ const renderer = createPptxThumbnailRenderer(presentation, {
167
+ fonts: {
168
+ loadEmbeddedFonts: false,
169
+ waitForFonts: false,
170
+ },
171
+ concurrency: 2,
172
+ onPerformanceMeasurement: recordMeasurement,
173
+ });
174
+
175
+ const thumbnail = await renderer.renderSlide(0, {
176
+ maxWidth: 240,
177
+ maxHeight: 135,
178
+ output: 'blob',
179
+ signal: abortController.signal,
180
+ });
181
+
182
+ image.src = URL.createObjectURL(thumbnail.data);
183
+ renderer.destroy();
184
+ ```
185
+
186
+ The output can be `blob` (PNG, the default), `canvas`, `imageBitmap`, or `svg`. `renderSlides()`
187
+ accepts an explicit index list, preserves its order, and never initializes other slides. Both
188
+ single and batch requests use the renderer's bounded queue. By default, the thumbnail-specific
189
+ font policy skips embedded fonts, global font readiness, and missing-font probing; callers can opt
190
+ back into any of those behaviors through `fonts`.
191
+
192
+ Performance observers receive `download`, `wasm-parsing`, `embedded-font-preparation`,
193
+ `slide-dom-svg-rendering`, `image-decoding`, and `raster-encoding` measurements as applicable. Each
194
+ render result also contains its slide-specific measurements.
195
+
153
196
  ## Thumbnail hook
154
197
 
155
198
  `usePptxViewerThumbnails` exposes detached slide previews for a consumer-owned filmstrip. PPTX
package/dist/index.d.ts CHANGED
@@ -373,6 +373,14 @@ interface ParsedPresentation {
373
373
  readonly document: PresentationDocument;
374
374
  readonly warnings: readonly PresentationWarning[];
375
375
  }
376
+ type PptxPerformancePhase = 'download' | 'wasm-parsing' | 'embedded-font-preparation' | 'slide-dom-svg-rendering' | 'image-decoding' | 'raster-encoding';
377
+ interface PptxPerformanceMeasurement {
378
+ /** Wall-clock duration for this phase. */
379
+ durationMs: number;
380
+ phase: PptxPerformancePhase;
381
+ /** Present for work attributable to one slide. */
382
+ slideIndex?: number;
383
+ }
376
384
  type PresentationSource = BinaryPresentationSource | PresentationDocument | ParsedPresentation;
377
385
  type ViewerMode = 'slide' | 'continuous';
378
386
  type FitMode = 'contain' | 'none';
@@ -381,6 +389,8 @@ interface ParsePresentationOptions {
381
389
  formatHint?: PresentationFormat;
382
390
  maxInputBytes?: number;
383
391
  fetchInit?: Omit<RequestInit, 'signal'>;
392
+ /** Receives cold-start download and native parsing timings. */
393
+ onPerformanceMeasurement?: (measurement: PptxPerformanceMeasurement) => void;
384
394
  }
385
395
  interface VirtualizationOptions {
386
396
  /**
@@ -466,6 +476,55 @@ interface PptxSlideThumbnailRenderOptions {
466
476
  /** Rendered thumbnail width in CSS pixels. */
467
477
  width?: number;
468
478
  }
479
+ type PptxThumbnailOutput = 'blob' | 'canvas' | 'imageBitmap' | 'svg';
480
+ interface PptxThumbnailRendererOptions {
481
+ /**
482
+ * Thumbnail-specific font policy. Defaults to skipping embedded fonts and
483
+ * not waiting for the global font set.
484
+ */
485
+ fonts?: PptxFontOptions;
486
+ /** Maximum number of slide renders executing at once. Default `2`. */
487
+ concurrency?: number;
488
+ onPerformanceMeasurement?: (measurement: PptxPerformanceMeasurement) => void;
489
+ onWarning?: (warning: PresentationWarning) => void;
490
+ }
491
+ interface PptxThumbnailRenderOptions {
492
+ maxHeight?: number;
493
+ maxWidth?: number;
494
+ /** Output pixel density. Default `1`. */
495
+ pixelRatio?: number;
496
+ output?: PptxThumbnailOutput;
497
+ /** PNG encoding quality where supported. */
498
+ quality?: number;
499
+ signal?: AbortSignal;
500
+ }
501
+ interface PptxThumbnailRenderResult<T> {
502
+ data: T;
503
+ height: number;
504
+ measurements: readonly PptxPerformanceMeasurement[];
505
+ output: PptxThumbnailOutput;
506
+ slideIndex: number;
507
+ width: number;
508
+ }
509
+ interface PptxThumbnailRenderer {
510
+ readonly presentation: ParsedPresentation;
511
+ readonly ready: Promise<void>;
512
+ renderSlide(slideIndex: number, options: PptxThumbnailRenderOptions & {
513
+ output: 'canvas';
514
+ }): Promise<PptxThumbnailRenderResult<HTMLCanvasElement>>;
515
+ renderSlide(slideIndex: number, options: PptxThumbnailRenderOptions & {
516
+ output: 'imageBitmap';
517
+ }): Promise<PptxThumbnailRenderResult<ImageBitmap>>;
518
+ renderSlide(slideIndex: number, options: PptxThumbnailRenderOptions & {
519
+ output: 'svg';
520
+ }): Promise<PptxThumbnailRenderResult<string>>;
521
+ renderSlide(slideIndex: number, options?: PptxThumbnailRenderOptions & {
522
+ output?: 'blob';
523
+ }): Promise<PptxThumbnailRenderResult<Blob>>;
524
+ /** Renders exactly the supplied indexes, preserving their order. */
525
+ renderSlides(slideIndexes: readonly number[], options?: PptxThumbnailRenderOptions): Promise<PptxThumbnailRenderResult<Blob | HTMLCanvasElement | ImageBitmap | string>[]>;
526
+ destroy(): void;
527
+ }
469
528
  interface PptxSlideThumbnailRenderWindow {
470
529
  /**
471
530
  * Slide indexes whose attached thumbnail containers should render first.
@@ -582,6 +641,8 @@ interface ReactPptxViewerProps extends Omit<HTMLAttributes<HTMLDivElement>, 'chi
582
641
  onSlideUnmounted?: (index: number) => void;
583
642
  onSearchResults?: (results: readonly PresentationSearchResult[]) => void;
584
643
  onThumbnailRendered?: (index: number, element: HTMLElement) => void;
644
+ /** Receives parsing, font preparation, and rendering timings. */
645
+ onPerformanceMeasurement?: (measurement: PptxPerformanceMeasurement) => void;
585
646
  /** Supplies the internal slide surface to host integrations and test harnesses. */
586
647
  onViewportReady?: (element: HTMLDivElement) => void;
587
648
  ref?: Ref<PptxViewerController>;
@@ -628,8 +689,10 @@ declare function usePptxViewer(): UsePptxViewerResult;
628
689
  */
629
690
  declare function usePptxViewerThumbnails(controller: PptxViewerController | null | undefined, options?: UsePptxViewerThumbnailsOptions): PptxViewerThumbnails;
630
691
 
692
+ declare function createPptxThumbnailRenderer(presentation: ParsedPresentation, options?: PptxThumbnailRendererOptions): PptxThumbnailRenderer;
693
+
631
694
  /** Cross-platform, metrically similar substitutions for common Office typefaces. */
632
695
  declare const OFFICE_FONT_FALLBACKS: Readonly<Record<string, readonly string[]>>;
633
696
  declare function resolvePptxFontFamily(fontFamily: string, options?: Pick<PptxFontOptions, 'fallbacks' | 'fallbackFamilies' | 'useOfficeFallbacks'>): string;
634
697
 
635
- export { type BinaryPresentationSource, type FitMode, OFFICE_FONT_FALLBACKS, type ParsePresentationOptions, type ParsedPresentation, type PptxFontOptions, type PptxFontSource, type PptxSlideThumbnailItem, type PptxSlideThumbnailRenderOptions, type PptxSlideThumbnailRenderWindow, type PptxSlideThumbnailResolution, type PptxSlideThumbnailStatus, type PptxViewerController, PptxViewerError, type PptxViewerThumbnails, type PresentationAsset, type PresentationDocument, type PresentationEmbeddedFont, type PresentationFormat, type PresentationMetadata, type PresentationSearchResult, type PresentationSlide, type PresentationSource, type PresentationTheme, type PresentationWarning, ReactPptxViewer, type ReactPptxViewerProps, type SearchHighlightOptions, type Slide, type SlideComment, type SlideLayout, type SlideMaster, type SlideNode, type SlideNote, type ThumbnailRenderContext, type UsePptxPresentationState, type UsePptxViewerResult, type UsePptxViewerThumbnailsOptions, type ViewerMode, type ViewerSearchOptions, type VirtualizationOptions, type WasmSource, type WorkerWasmSource, initWasm, parsePresentation, presentationParsingDefaults, resolvePptxFontFamily, setWasmSource, usePptxModel, usePptxPresentation, usePptxViewer, usePptxViewerThumbnails };
698
+ export { type BinaryPresentationSource, type FitMode, OFFICE_FONT_FALLBACKS, type ParsePresentationOptions, type ParsedPresentation, type PptxFontOptions, type PptxFontSource, type PptxPerformanceMeasurement, type PptxPerformancePhase, type PptxSlideThumbnailItem, type PptxSlideThumbnailRenderOptions, type PptxSlideThumbnailRenderWindow, type PptxSlideThumbnailResolution, type PptxSlideThumbnailStatus, type PptxThumbnailOutput, type PptxThumbnailRenderOptions, type PptxThumbnailRenderResult, type PptxThumbnailRenderer, type PptxThumbnailRendererOptions, type PptxViewerController, PptxViewerError, type PptxViewerThumbnails, type PresentationAsset, type PresentationDocument, type PresentationEmbeddedFont, type PresentationFormat, type PresentationMetadata, type PresentationSearchResult, type PresentationSlide, type PresentationSource, type PresentationTheme, type PresentationWarning, ReactPptxViewer, type ReactPptxViewerProps, type SearchHighlightOptions, type Slide, type SlideComment, type SlideLayout, type SlideMaster, type SlideNode, type SlideNote, type ThumbnailRenderContext, type UsePptxPresentationState, type UsePptxViewerResult, type UsePptxViewerThumbnailsOptions, type ViewerMode, type ViewerSearchOptions, type VirtualizationOptions, type WasmSource, type WorkerWasmSource, createPptxThumbnailRenderer, initWasm, parsePresentation, presentationParsingDefaults, resolvePptxFontFamily, setWasmSource, usePptxModel, usePptxPresentation, usePptxViewer, usePptxViewerThumbnails };