docgen-utils 1.0.31 → 1.0.32

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.
@@ -1,15 +1,10 @@
1
1
  /**
2
2
  * Export slides command - converts HTML slides to PPTX using Playwright
3
3
  *
4
- * Strategy: Navigate to the directory of the first HTML file using file://
5
- * protocol, then inject the bundle and run the conversion. This gives the
6
- * page (and the nested iframe created by addSlideFromHtml) a real browsing
7
- * context so that:
8
- * - Google Fonts <link> tags load correctly → accurate font names/sizes
9
- * - --disable-web-security allows cross-origin images on canvas without
10
- * tainting → CSS filters, mask-image, and icon font rendering all work
11
- * - No need to pre-embed images as data URIs (avoids regex fragility and
12
- * potential base64 corruption by transformHtmlForPptx)
4
+ * Architecture: Pipelined processing for maximum speed:
5
+ * - Parse slides in browser (batched for stability)
6
+ * - Start fetching images immediately as slides are parsed
7
+ * - Generate PPTX slides as soon as their images are ready
13
8
  */
14
9
  export declare function exportSlides(filePaths: string[], outDir: string, outputName?: string, pdf?: boolean): Promise<void>;
15
10
  //# sourceMappingURL=export-slides.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"export-slides.d.ts","sourceRoot":"","sources":["../../../../packages/cli/commands/export-slides.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAsEH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAoIhI"}
1
+ {"version":3,"file":"export-slides.d.ts","sourceRoot":"","sources":["../../../../packages/cli/commands/export-slides.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA6EH,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAwQhI"}
@@ -1,70 +1,81 @@
1
1
  /**
2
2
  * Export slides command - converts HTML slides to PPTX using Playwright
3
3
  *
4
- * Strategy: Navigate to the directory of the first HTML file using file://
5
- * protocol, then inject the bundle and run the conversion. This gives the
6
- * page (and the nested iframe created by addSlideFromHtml) a real browsing
7
- * context so that:
8
- * - Google Fonts <link> tags load correctly → accurate font names/sizes
9
- * - --disable-web-security allows cross-origin images on canvas without
10
- * tainting → CSS filters, mask-image, and icon font rendering all work
11
- * - No need to pre-embed images as data URIs (avoids regex fragility and
12
- * potential base64 corruption by transformHtmlForPptx)
4
+ * Architecture: Pipelined processing for maximum speed:
5
+ * - Parse slides in browser (batched for stability)
6
+ * - Start fetching images immediately as slides are parsed
7
+ * - Generate PPTX slides as soon as their images are ready
13
8
  */
14
9
  import * as fs from "node:fs";
15
10
  import * as path from "node:path";
16
11
  import { fileURLToPath } from "node:url";
17
12
  import { chromium } from "playwright";
18
- import { fetchWithProxy } from "../../shared/fetch-with-proxy";
19
13
  import { convertOfficeToPdf } from "../../shared/convert-to-pdf";
14
+ import { fetchWithProxy } from "../../shared/fetch-with-proxy";
15
+ import PptxGenJS from "../../slides/vendor/pptxgen";
16
+ import { addElementsToSlide, applyBackground } from "../../slides/convert";
20
17
  const __filename = fileURLToPath(import.meta.url);
21
18
  const __dirname = path.dirname(__filename);
22
19
  /**
23
- * Pre-fetch external images and convert them to data URIs.
24
- * This bypasses CORS restrictions by fetching images in Node.js
25
- * before passing HTML to the browser context.
20
+ * Fetch an image URL and convert to base64 data URL using Node.js.
26
21
  */
27
- async function embedExternalImages(html) {
28
- // Find all external image URLs in src attributes (allow whitespace around URL)
29
- const imgRegex = /<img\s+([^>]*?)src="\s*(https?:\/\/[^"]+?)\s*"([^>]*)>/gi;
30
- const matches = [...html.matchAll(imgRegex)];
31
- if (matches.length === 0) {
32
- return html;
33
- }
34
- // Collect unique URLs (trimmed)
22
+ async function fetchImageAsDataUrlNode(url) {
23
+ const response = await fetchWithProxy(url);
24
+ if (!response.ok) {
25
+ throw new Error(`Failed to fetch image: ${response.status}`);
26
+ }
27
+ const arrayBuffer = await response.arrayBuffer();
28
+ const buffer = Buffer.from(arrayBuffer);
29
+ // Determine MIME type from URL or content-type header
30
+ const contentType = response.headers.get("content-type") || "image/png";
31
+ const base64 = buffer.toString("base64");
32
+ return `data:${contentType};base64,${base64}`;
33
+ }
34
+ /**
35
+ * Collect all image URLs from parsed slide data.
36
+ */
37
+ function collectImageUrls(slideData) {
35
38
  const urls = new Set();
36
- for (const match of matches) {
37
- urls.add(match[2]);
38
- }
39
- // Fetch all images in parallel
40
- const urlToDataUri = new Map();
41
- await Promise.all(Array.from(urls).map(async (url) => {
42
- try {
43
- const response = await fetchWithProxy(url);
44
- if (response.ok) {
45
- const buffer = await response.arrayBuffer();
46
- const contentType = response.headers.get('content-type') || 'image/jpeg';
47
- const base64 = Buffer.from(buffer).toString('base64');
48
- const dataUri = `data:${contentType};base64,${base64}`;
49
- urlToDataUri.set(url, dataUri);
39
+ // Background image
40
+ if (slideData.background.type === "image" && slideData.background.path) {
41
+ const src = slideData.background.path;
42
+ if (!src.startsWith("data:"))
43
+ urls.add(src);
44
+ }
45
+ // Element images
46
+ for (const el of slideData.elements) {
47
+ if (el.type === "image" || el.type === "backgroundImage" || el.type === "slideBackgroundImage") {
48
+ if (el.src && !el.src.startsWith("data:")) {
49
+ urls.add(el.src);
50
50
  }
51
51
  }
52
- catch {
53
- // Failed to fetch - image will be skipped during conversion
54
- console.warn(`Failed to fetch image: ${url}`);
55
- }
56
- }));
57
- // Replace src values with data URIs, handling whitespace around URLs
58
- html = html.replace(/<img(\s+[^>]*?)src="\s*(https?:\/\/[^"]+?)\s*"([^>]*)>/gi, (match, before, url, after) => {
59
- const dataUri = urlToDataUri.get(url);
60
- if (dataUri) {
61
- return `<img${before}src="${dataUri}"${after}>`;
52
+ }
53
+ return urls;
54
+ }
55
+ /**
56
+ * Replace external image URLs with data URLs in parsed slide data.
57
+ */
58
+ function injectImageDataUrls(slideData, imageCache) {
59
+ // Background image
60
+ if (slideData.background.type === "image" && slideData.background.path) {
61
+ const dataUrl = imageCache.get(slideData.background.path);
62
+ if (dataUrl)
63
+ slideData.background.path = dataUrl;
64
+ }
65
+ // Element images
66
+ for (const el of slideData.elements) {
67
+ if (el.type === "image" || el.type === "backgroundImage" || el.type === "slideBackgroundImage") {
68
+ if (el.src && !el.src.startsWith("data:")) {
69
+ const dataUrl = imageCache.get(el.src);
70
+ if (dataUrl)
71
+ el.src = dataUrl;
72
+ }
62
73
  }
63
- return match;
64
- });
65
- return html;
74
+ }
66
75
  }
67
76
  export async function exportSlides(filePaths, outDir, outputName, pdf = false) {
77
+ // Filter out empty strings (e.g., from trailing commas in --files argument)
78
+ filePaths = filePaths.filter(p => p.trim() !== "");
68
79
  if (filePaths.length === 0) {
69
80
  throw new Error("No input files provided");
70
81
  }
@@ -78,7 +89,7 @@ export async function exportSlides(filePaths, outDir, outputName, pdf = false) {
78
89
  absolutePaths.push(absolutePath);
79
90
  }
80
91
  console.log(`Exporting ${absolutePaths.length} slide(s) to ${pdf ? "PDF" : "PPTX"}`);
81
- // Read the bundle which contains all the PPTX generation code
92
+ // Read the bundle which contains parsing code
82
93
  let bundlePath = path.resolve(__dirname, "bundle.min.js");
83
94
  if (!fs.existsSync(bundlePath)) {
84
95
  bundlePath = path.resolve(__dirname, "..", "..", "..", "dist/bundle.min.js");
@@ -86,23 +97,70 @@ export async function exportSlides(filePaths, outDir, outputName, pdf = false) {
86
97
  if (!fs.existsSync(bundlePath)) {
87
98
  throw new Error(`Bundle not found: ${bundlePath}. Run 'npm run build' first.`);
88
99
  }
89
- const bundleCode = fs.readFileSync(bundlePath, "utf-8");
90
- // Read all HTML files and embed external images as data URIs
91
- // This bypasses CORS restrictions by fetching images in Node.js
92
- const htmlContents = [];
93
- for (const p of absolutePaths) {
94
- let html = fs.readFileSync(p, "utf-8");
95
- html = await embedExternalImages(html);
96
- htmlContents.push(html);
97
- }
98
- // Launch browser with --disable-web-security so cross-origin images can be
99
- // rendered on canvas without tainting (needed for CSS filters, mask-image,
100
- // and icon font canvas rendering inside addSlideFromHtml).
100
+ const bundleJs = fs.readFileSync(bundlePath, "utf-8");
101
+ // Shared image cache - populated as images are fetched
102
+ const imageCache = new Map();
103
+ const imageFetchPromises = new Map();
104
+ // Start fetching an image if not already fetching
105
+ function startImageFetch(url) {
106
+ if (imageFetchPromises.has(url))
107
+ return;
108
+ const promise = fetchImageAsDataUrlNode(url)
109
+ .then(dataUrl => { imageCache.set(url, dataUrl); })
110
+ .catch(() => { });
111
+ imageFetchPromises.set(url, promise);
112
+ }
113
+ // Wait for all images needed by a slide
114
+ async function waitForSlideImages(slideData) {
115
+ const urls = collectImageUrls(slideData);
116
+ const promises = Array.from(urls).map(url => imageFetchPromises.get(url)).filter(Boolean);
117
+ await Promise.all(promises);
118
+ }
119
+ // Initialize PPTX early
120
+ const pptx = new PptxGenJS();
121
+ pptx.layout = "LAYOUT_16x9";
122
+ pptx.author = "docgen";
123
+ pptx.title = "Presentation";
124
+ // Pre-create slides to maintain order (PptxGenJS adds slides sequentially)
125
+ const slideSlots = [];
126
+ for (let i = 0; i < absolutePaths.length; i++) {
127
+ slideSlots.push({ slide: pptx.addSlide(), generated: false });
128
+ }
129
+ // Track progress
130
+ let parsedCount = 0;
131
+ let generatedCount = 0;
132
+ // Queue of parsed slides ready for generation
133
+ const parsedSlides = [];
134
+ // Serialized slide generation - only one generation loop runs at a time
135
+ let generationChain = Promise.resolve();
136
+ function queueGeneration() {
137
+ generationChain = generationChain.then(async () => {
138
+ while (true) {
139
+ // Find next slide in order
140
+ const nextIndex = generatedCount;
141
+ const entry = parsedSlides.find(p => p.index === nextIndex);
142
+ if (!entry)
143
+ break;
144
+ // Wait for this slide's images
145
+ await entry.imagesReady;
146
+ // Generate slide
147
+ const { slideData } = entry;
148
+ const slot = slideSlots[nextIndex];
149
+ injectImageDataUrls(slideData, imageCache);
150
+ await applyBackground(slideData.background, slot.slide);
151
+ await addElementsToSlide(slideData.elements, slot.slide, pptx);
152
+ slot.generated = true;
153
+ generatedCount++;
154
+ console.log(` Slide ${generatedCount}/${absolutePaths.length} done`);
155
+ }
156
+ });
157
+ }
158
+ // Launch browser
101
159
  const launchOptions = {
102
160
  headless: true,
103
161
  args: ["--disable-web-security"],
104
162
  };
105
- const proxyServer = process.env.HTTPS_PROXY || process.env.HTTP_PROXY;
163
+ const proxyServer = process.env.HTTPS_PROXY || process.env.HTTP_PROXY || process.env.https_proxy || process.env.http_proxy;
106
164
  if (proxyServer) {
107
165
  launchOptions.proxy = { server: proxyServer };
108
166
  }
@@ -113,51 +171,126 @@ export async function exportSlides(filePaths, outDir, outputName, pdf = false) {
113
171
  viewport: { width: 960, height: 540 },
114
172
  ignoreHTTPSErrors: true,
115
173
  });
116
- const page = await context.newPage();
117
- // Navigate to the directory of the first HTML file so the page has a real
118
- // file:// origin. This ensures the nested iframe created by
119
- // addSlideFromHtml (via blob URL) can load Google Fonts and other external
120
- // resources, giving getComputedStyle() accurate font names and sizes.
121
- const htmlDir = path.dirname(absolutePaths[0]);
122
- await page.goto(`file://${htmlDir}/`, { waitUntil: "networkidle" });
123
- // Inject the bundle into the page
124
- await page.evaluate((code) => {
125
- const script = document.createElement("script");
126
- script.textContent = code;
127
- document.head.appendChild(script);
128
- }, bundleCode);
129
- // Wait for the bundle to initialise on the page
130
- await page.waitForFunction(() => !!window.docgen);
131
- // Generate PPTX in browser
132
- const pptxBuffer = await page.evaluate(async ({ htmlContents }) => {
133
- const docgen = window.docgen;
134
- // Create PptxGenJS instance
135
- const pptx = new docgen.PptxGenJS();
136
- pptx.layout = "LAYOUT_16x9";
137
- pptx.author = "docgen";
138
- pptx.title = "Presentation";
139
- // Add each slide
140
- for (const htmlContent of htmlContents) {
141
- const transformedHtml = docgen.transformHtmlForPptx(htmlContent);
142
- await docgen.addSlideFromHtml(transformedHtml, pptx);
174
+ // Block external image loading - we fetch images in Node.js instead
175
+ await context.route('**/*', route => {
176
+ const request = route.request();
177
+ const url = request.url();
178
+ if (url.startsWith('blob:') || url.startsWith('data:')) {
179
+ return route.continue();
180
+ }
181
+ if (request.resourceType() === 'image') {
182
+ return route.abort();
143
183
  }
144
- // Generate as base64
145
- const base64 = await pptx.write({ outputType: "base64" });
146
- return base64;
147
- }, { htmlContents });
148
- await page.close();
184
+ return route.continue();
185
+ });
186
+ // Parse slides in batches, but start processing immediately
187
+ const MAX_CONCURRENT = 4;
188
+ for (let batchStart = 0; batchStart < absolutePaths.length; batchStart += MAX_CONCURRENT) {
189
+ const batchEnd = Math.min(batchStart + MAX_CONCURRENT, absolutePaths.length);
190
+ const batchPaths = absolutePaths.slice(batchStart, batchEnd);
191
+ const batchPromises = batchPaths.map(async (slidePath, batchIndex) => {
192
+ const index = batchStart + batchIndex;
193
+ const page = await context.newPage();
194
+ page.setDefaultTimeout(60000);
195
+ await page.goto(`file://${slidePath}`, { waitUntil: "domcontentloaded" });
196
+ await page.addScriptTag({ content: bundleJs });
197
+ await page.waitForFunction("typeof window.docgen !== 'undefined'");
198
+ await page.evaluate(`(async function() {
199
+ if (document.fonts && document.fonts.ready) {
200
+ await Promise.race([
201
+ document.fonts.ready,
202
+ new Promise(r => setTimeout(r, 500))
203
+ ]);
204
+ }
205
+ })()`);
206
+ const slideDataJson = await page.evaluate(`(async function() {
207
+ const docgen = window.docgen;
208
+ const html = document.documentElement.outerHTML;
209
+ const transformedHtml = docgen.transformHtmlForPptx(html);
210
+
211
+ const iframe = document.createElement('iframe');
212
+ iframe.style.cssText = 'position:absolute;left:-9999px;width:960px;height:540px;border:none;';
213
+
214
+ const blob = new Blob([transformedHtml], { type: 'text/html' });
215
+ const blobUrl = URL.createObjectURL(blob);
216
+
217
+ return new Promise((resolve) => {
218
+ iframe.onload = async () => {
219
+ URL.revokeObjectURL(blobUrl);
220
+
221
+ const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
222
+ const win = iframe.contentWindow;
223
+
224
+ if (win.document.fonts && win.document.fonts.ready) {
225
+ await Promise.race([
226
+ win.document.fonts.ready,
227
+ new Promise(r => setTimeout(r, 500))
228
+ ]);
229
+ }
230
+
231
+ try {
232
+ const slideData = docgen.parseSlideHtml(iframeDoc);
233
+ iframe.parentNode.removeChild(iframe);
234
+ resolve(JSON.stringify(slideData));
235
+ } catch(e) {
236
+ iframe.parentNode.removeChild(iframe);
237
+ resolve(JSON.stringify({ error: e.message }));
238
+ }
239
+ };
240
+
241
+ iframe.onerror = () => {
242
+ URL.revokeObjectURL(blobUrl);
243
+ iframe.parentNode?.removeChild(iframe);
244
+ resolve(JSON.stringify({ error: 'iframe load error' }));
245
+ };
246
+
247
+ iframe.src = blobUrl;
248
+ document.body.appendChild(iframe);
249
+
250
+ setTimeout(() => {
251
+ if (iframe.parentNode) {
252
+ iframe.parentNode.removeChild(iframe);
253
+ resolve(JSON.stringify({ error: 'timeout' }));
254
+ }
255
+ }, 10000);
256
+ });
257
+ })()`);
258
+ await page.close();
259
+ if (!slideDataJson) {
260
+ throw new Error(`Failed to parse slide ${index + 1}: ${slidePath} - null result`);
261
+ }
262
+ const parsed = JSON.parse(slideDataJson);
263
+ if (typeof parsed === 'object' && 'error' in parsed) {
264
+ throw new Error(`Failed to parse slide ${index + 1}: ${slidePath} - ${parsed.error}`);
265
+ }
266
+ const slideData = parsed;
267
+ parsedCount++;
268
+ console.log(` Parsed ${parsedCount}/${absolutePaths.length}`);
269
+ // Start fetching images for this slide immediately
270
+ const urls = collectImageUrls(slideData);
271
+ urls.forEach(url => startImageFetch(url));
272
+ // Create promise that resolves when all images for this slide are ready
273
+ const imagesReady = waitForSlideImages(slideData);
274
+ // Add to queue and trigger generation
275
+ parsedSlides.push({ index, slideData, imagesReady });
276
+ queueGeneration();
277
+ });
278
+ await Promise.all(batchPromises);
279
+ }
149
280
  await context.close();
150
- // Determine output filename - use provided name, or derive from input file(s)
281
+ await browser.close();
282
+ // Wait for all slide generation to complete
283
+ await generationChain;
284
+ // Write final PPTX
285
+ const base64 = await pptx.write({ outputType: "base64" });
286
+ const pptxBuffer = Buffer.from(base64, "base64");
151
287
  const firstBaseName = path.basename(absolutePaths[0], ".html");
152
288
  const finalName = outputName || (absolutePaths.length === 1 ? firstBaseName : "presentation");
153
289
  const pptxOutputPath = path.join(outDir, `${finalName}.pptx`);
154
- // Convert base64 to buffer and write to file
155
- const buffer = Buffer.from(pptxBuffer, "base64");
156
- fs.writeFileSync(pptxOutputPath, buffer);
290
+ fs.writeFileSync(pptxOutputPath, pptxBuffer);
157
291
  if (pdf) {
158
292
  console.log("Converting to PDF via LibreOffice...");
159
293
  const pdfPath = convertOfficeToPdf(pptxOutputPath, outDir);
160
- // Remove intermediate PPTX file
161
294
  fs.unlinkSync(pptxOutputPath);
162
295
  console.log(`Output: ${pdfPath}`);
163
296
  }
@@ -166,7 +299,7 @@ export async function exportSlides(filePaths, outDir, outputName, pdf = false) {
166
299
  }
167
300
  }
168
301
  finally {
169
- await browser.close();
302
+ await browser.close().catch(() => { });
170
303
  }
171
304
  }
172
305
  //# sourceMappingURL=export-slides.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"export-slides.js","sourceRoot":"","sources":["../../../../packages/cli/commands/export-slides.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"export-slides.js","sourceRoot":"","sources":["../../../../packages/cli/commands/export-slides.ts"],"names":[],"mappings":"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"}
@@ -29,6 +29,8 @@ export declare function applyBackground(background: SlideBackground, slide: Slid
29
29
  * 1. First pass - adds `slideBackgroundImage` elements (rendered behind everything).
30
30
  * 2. Second pass - adds all other element types (image, backgroundImage, line, shape, list, text).
31
31
  *
32
+ * Images are prefetched in parallel at the start for better performance.
33
+ *
32
34
  * @param elements - The parsed slide elements array.
33
35
  * @param slide - The target PptxGenJS Slide instance.
34
36
  * @param pres - The PptxGenJS presentation instance (needed for `pres.ShapeType`).
@@ -1 +1 @@
1
- {"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../../../packages/slides/convert.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,KAAK,EAKN,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EAEb,MAAM,UAAU,CAAC;AA0FlB;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,UAAU,SAAI,EACd,cAAc,SAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CA2CjB;AAMD;;GAEG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,eAAe,EAC3B,KAAK,EAAE,KAAK,GACX,OAAO,CAAC,IAAI,CAAC,CAkBf;AAoFD;;;;;;;;;;;GAWG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,YAAY,EAAE,EACxB,KAAK,EAAE,KAAK,EAEZ,IAAI,EAAE,GAAG,GACR,OAAO,CAAC,IAAI,CAAC,CAqff"}
1
+ {"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../../../packages/slides/convert.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,KAAK,EAKN,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EAEb,MAAM,UAAU,CAAC;AA0FlB;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,UAAU,SAAI,EACd,cAAc,SAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CA2CjB;AAMD;;GAEG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,eAAe,EAC3B,KAAK,EAAE,KAAK,GACX,OAAO,CAAC,IAAI,CAAC,CAkBf;AA0DD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,YAAY,EAAE,EACxB,KAAK,EAAE,KAAK,EAEZ,IAAI,EAAE,GAAG,GACR,OAAO,CAAC,IAAI,CAAC,CAqhBf"}
@@ -208,31 +208,6 @@ function clipToSlide(pos) {
208
208
  // ---------------------------------------------------------------------------
209
209
  // addElementsToSlide
210
210
  // ---------------------------------------------------------------------------
211
- /**
212
- * Resolve an image source to a PptxGenJS-compatible `{ data: string }` object.
213
- *
214
- * Data URIs are used directly. External/relative URLs are fetched and converted
215
- * to data URLs via {@link fetchImageAsDataUrl}.
216
- *
217
- * Returns `null` when the fetch fails (e.g. CORS), allowing the caller to skip
218
- * the image with a warning.
219
- */
220
- async function getImageSource(src) {
221
- if (src.startsWith('data:')) {
222
- return { data: src };
223
- }
224
- else {
225
- try {
226
- const dataUrl = await fetchImageAsDataUrl(src);
227
- return { data: dataUrl };
228
- }
229
- catch (e) {
230
- const message = e instanceof Error ? e.message : String(e);
231
- console.warn(`Could not fetch image ${src}: ${message}`);
232
- return null;
233
- }
234
- }
235
- }
236
211
  /**
237
212
  * Add all slide elements to a PptxGenJS Slide.
238
213
  *
@@ -240,6 +215,8 @@ async function getImageSource(src) {
240
215
  * 1. First pass - adds `slideBackgroundImage` elements (rendered behind everything).
241
216
  * 2. Second pass - adds all other element types (image, backgroundImage, line, shape, list, text).
242
217
  *
218
+ * Images are prefetched in parallel at the start for better performance.
219
+ *
243
220
  * @param elements - The parsed slide elements array.
244
221
  * @param slide - The target PptxGenJS Slide instance.
245
222
  * @param pres - The PptxGenJS presentation instance (needed for `pres.ShapeType`).
@@ -248,10 +225,41 @@ async function getImageSource(src) {
248
225
  export async function addElementsToSlide(elements, slide,
249
226
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
250
227
  pres) {
228
+ // ---- Prefetch all images in parallel ----
229
+ const imageUrls = new Set();
230
+ for (const el of elements) {
231
+ if (el.type === 'image' || el.type === 'backgroundImage' || el.type === 'slideBackgroundImage') {
232
+ if (el.src && !el.src.startsWith('data:')) {
233
+ imageUrls.add(el.src);
234
+ }
235
+ }
236
+ }
237
+ const imageCache = new Map();
238
+ if (imageUrls.size > 0) {
239
+ const fetchPromises = Array.from(imageUrls).map(async (url) => {
240
+ try {
241
+ const dataUrl = await fetchImageAsDataUrl(url);
242
+ imageCache.set(url, { data: dataUrl });
243
+ }
244
+ catch (e) {
245
+ const message = e instanceof Error ? e.message : String(e);
246
+ console.warn(`Could not fetch image ${url}: ${message}`);
247
+ imageCache.set(url, null);
248
+ }
249
+ });
250
+ await Promise.all(fetchPromises);
251
+ }
252
+ // Helper to get image from cache or return data URI directly
253
+ const getCachedImageSource = (src) => {
254
+ if (src.startsWith('data:')) {
255
+ return { data: src };
256
+ }
257
+ return imageCache.get(src) ?? null;
258
+ };
251
259
  // ---- First pass: slide background images ----
252
260
  for (const el of elements) {
253
261
  if (el.type === 'slideBackgroundImage') {
254
- const imgSrc = await getImageSource(el.src);
262
+ const imgSrc = getCachedImageSource(el.src);
255
263
  if (!imgSrc) {
256
264
  console.warn(`Skipping slide background image (CORS failure): ${el.src}`);
257
265
  continue;
@@ -313,7 +321,7 @@ pres) {
313
321
  el.position.h = clipped.h;
314
322
  }
315
323
  if (el.type === 'image') {
316
- const imgSrc = await getImageSource(el.src);
324
+ const imgSrc = getCachedImageSource(el.src);
317
325
  if (!imgSrc) {
318
326
  console.warn(`Skipping image (CORS failure): ${el.src}`);
319
327
  continue;
@@ -353,7 +361,7 @@ pres) {
353
361
  slide.addImage(imageOptions);
354
362
  }
355
363
  else if (el.type === 'backgroundImage') {
356
- const imgSrc = await getImageSource(el.src);
364
+ const imgSrc = getCachedImageSource(el.src);
357
365
  if (!imgSrc) {
358
366
  console.warn(`Skipping background image (CORS failure): ${el.src}`);
359
367
  continue;