### Workflow Engine Setup (TypeScript) Source: https://context7.com/pdfcrafttool/pdfcraft/llms.txt Demonstrates the setup and basic usage of a visual workflow system for PDF operations. It includes defining nodes and edges, validating the workflow structure, performing a topological sort for execution order, and identifying input/output nodes. Dependencies include types from '@/types/workflow' and functions from '@/lib/workflow/engine'. ```typescript import { validateWorkflow, topologicalSort, findInputNodes, findOutputNodes, createExecutionState, getNodeInputFiles, } from '@/lib/workflow/engine'; import type { WorkflowNode, WorkflowEdge } from '@/types/workflow'; // Define workflow nodes const nodes: WorkflowNode[] = [ { id: 'node-1', type: 'tool', position: { x: 100, y: 100 }, data: { toolId: 'merge-pdf', label: 'Merge PDFs', outputFormat: '.pdf', acceptedFormats: ['.pdf'], status: 'idle', progress: 0, }, }, { id: 'node-2', type: 'tool', position: { x: 300, y: 100 }, data: { toolId: 'compress-pdf', label: 'Compress', outputFormat: '.pdf', acceptedFormats: ['.pdf'], status: 'idle', progress: 0, }, }, ]; // Define connections between nodes const edges: WorkflowEdge[] = [ { id: 'edge-1', source: 'node-1', target: 'node-2' }, ]; // Validate the workflow const validation = validateWorkflow(nodes, edges); if (!validation.isValid) { validation.errors.forEach(err => console.error(err.message)); } // Get execution order (topological sort) const executionOrder = topologicalSort(nodes, edges); // Result: ['node-1', 'node-2'] // Find entry and exit points const inputNodes = findInputNodes(nodes, edges); // Nodes that receive initial files const outputNodes = findOutputNodes(nodes, edges); // Nodes that produce final output // Create execution state for tracking progress const state = createExecutionState(nodes, edges); ``` -------------------------------- ### Install Dependencies and Build Project (npm) Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/DEPLOYMENT.md Installs project dependencies using npm and builds the project for production, generating static output in the 'out/' directory. This is a common first step for deployment. ```bash npm install npm run build ``` -------------------------------- ### Start Development Server Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/README.md Starts the PDFCraft development server using npm, yarn, or pnpm. This command enables hot reloading for a faster development experience. ```bash npm run dev # or yarn dev # or pnpm dev ``` -------------------------------- ### Deploying PDFCraft to Firebase Hosting Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/DEPLOYMENT.md Commands to install the Firebase CLI, initialize the hosting environment, and deploy the production build. This assumes the project has been built using npm run build. ```bash npm install -g firebase-tools firebase login firebase init hosting npm run build firebase deploy --only hosting ``` -------------------------------- ### Environment Variable Configuration Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/DEPLOYMENT.md Example of setting environment variables for the build process, such as site URLs and analytics IDs. ```bash NEXT_PUBLIC_SITE_URL=https://your-domain.com NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/README.md Installs the necessary Node.js dependencies for the PDFCraft project using npm, yarn, or pnpm. Ensure you have Node.js 18.17 or later installed. ```bash npm install # or yarn install # or pnpm install ``` -------------------------------- ### FileUploader Component Implementation (TypeScript) Source: https://context7.com/pdfcrafttool/pdfcraft/llms.txt Demonstrates the usage of the FileUploader component for selecting PDF files. It includes configuration for accepted file types, multiple file selection, size limits, and error handling. The example shows how to integrate the component into a React application. ```typescript import { FileUploader } from '@/components/tools/FileUploader'; function PDFTool() { const handleFilesSelected = (files: File[]) => { console.log('Selected files:', files); // Process files... }; const handleError = (error: string) => { alert(error); }; return ( ); } // Accept multiple file types ``` -------------------------------- ### Deploy to Netlify (Manual CLI) Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/DEPLOYMENT.md Manually deploys the project to Netlify using the Netlify CLI. This command builds the project and then deploys the contents of the 'out/' directory. ```bash npm install -g netlify-cli npm run build netlify deploy --prod --dir=out ``` -------------------------------- ### Local Previewing of Static Builds Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/DEPLOYMENT.md Methods to serve the static build output locally using Python, Node.js, or PHP for testing purposes. ```bash # Using Python cd out python -m http.server 8080 # Using Node.js serve npx serve out # Using PHP cd out php -S localhost:8080 ``` -------------------------------- ### Deploy to Vercel (Manual CLI) Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/DEPLOYMENT.md Manually deploys the project to Vercel using the Vercel CLI. This command assumes the project is already configured for Vercel, including settings in vercel.json for security and caching headers. ```bash npm install -g vercel vercel --prod ``` -------------------------------- ### AWS S3 and CloudFront Deployment for PDFCraft Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/DEPLOYMENT.md This section details deploying the PDFCraft application using AWS S3 for static website hosting and CloudFront for content delivery. It includes bash commands for building the site, syncing files to S3, and invalidating the CloudFront cache. It also outlines the necessary S3 bucket configuration and CloudFront response headers policy to enable SharedArrayBuffer. ```bash # Build the site npm run build # Upload to S3 aws s3 sync out/ s3://your-bucket-name --delete # Invalidate CloudFront cache aws cloudfront create-invalidation --distribution-id YOUR_DIST_ID --paths "/*" ``` -------------------------------- ### Initialize PDF.js Viewer Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/public/pdfjs-viewer/sign-viewer.html Sets up the PDF viewer instance using PDF.js library components. It configures the container, event bus, and link service to enable document rendering and annotation support. ```javascript import * as pdfjsLib from './pdf.mjs'; import { EventBus, PDFViewer, PDFLinkService } from './pdf_viewer.mjs'; pdfjsLib.GlobalWorkerOptions.workerSrc = './pdf.worker.mjs'; const eventBus = new EventBus(); const linkService = new PDFLinkService({ eventBus }); const pdfViewer = new PDFViewer({ container: document.getElementById('viewerContainer'), viewer: document.getElementById('viewer'), eventBus, linkService, annotationEditorMode: 1, enableScripting: true, renderer: 'canvas' }); linkService.setViewer(pdfViewer); ``` -------------------------------- ### Build Site for Nginx Deployment Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/DEPLOYMENT.md Builds the static site for deployment with Nginx. This command generates the 'out/' directory containing all static assets. ```bash npm run build ``` -------------------------------- ### Deploy to Cloudflare Pages (Manual CLI) Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/DEPLOYMENT.md Manually deploys the project to Cloudflare Pages using the Wrangler CLI. This command builds the project and then uploads the static output to Cloudflare Pages. ```bash npm install -g wrangler npm run build wrangler pages deploy out ``` -------------------------------- ### Copy Build Artifacts to Web Root (Bash) Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/DEPLOYMENT.md This command copies the compiled output of the PDFCraft tool from the 'out/' directory to the web server's root directory, typically '/var/www/html/'. This is a common first step for deploying static web applications. ```bash sudo cp -r out/* /var/www/html/ ``` -------------------------------- ### Run Project Tests Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/README.md Executes the project's test suite using Vitest. This command is used to verify the functionality and stability of the application. ```bash npm run test ``` -------------------------------- ### Run Docker Compose for PDFCraft Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/DEPLOYMENT.md Commands to manage the Docker containers for the PDFCraft project. Includes options for development and production modes, as well as stopping the containers. ```bash docker compose --profile dev up docker compose --profile prod up --build docker compose down ``` -------------------------------- ### Clone PDFCraft Repository Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/README.md Clones the PDFCraft project repository from GitHub. This is the first step to setting up the project locally. ```bash git clone https://github.com/PDFCraftTool/pdfcraft.git cd pdfcraft ``` -------------------------------- ### Build and Run PDFCraft with Docker Compose Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/README.md Builds and runs the PDFCraft application using Docker Compose. Supports both development mode with hot reloading and production mode with a static build. ```bash # Clone the repository git clone https://github.com/PDFCraftTool/pdfcraft.git cd pdfcraft # Development mode (with hot reload) docker compose --profile dev up # Production mode (static build + Nginx) docker compose --profile prod up --build ``` -------------------------------- ### Notify Parent Window of Initialization Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/public/pdfjs-viewer/sign-viewer.html Sends a postMessage to the parent window to signal that the PDF viewer has finished initializing. ```javascript window.parent.postMessage({ type: 'viewerReady' }, '*'); ``` -------------------------------- ### PDFCraft Processor Architecture Source: https://context7.com/pdfcrafttool/pdfcraft/llms.txt Guidelines for integrating with the PDFCraft processor-based architecture for client-side file manipulation. ```APIDOC ## PDFCraft Processor API ### Description PDFCraft uses a standardized processor-based architecture to perform client-side PDF operations. Each processor accepts input files and configuration options, providing progress tracking and cancellation support. ### Key Features - **Client-side Processing**: Ensures user privacy by keeping files local. - **Progress Tracking**: Supports real-time UI updates via callbacks. - **Cancellation**: Supports user-initiated abort of long-running operations. - **Composition**: Processors can be chained to create complex workflows (e.g., merge then compress). ### Integration Pattern 1. Import the specific processor. 2. Pass the File objects and configuration options. 3. Handle the `ProcessOutput` result. 4. Utilize the progress callback for UI feedback. ``` -------------------------------- ### Handle PDF Print and Download Actions Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/public/pdfjs-viewer/form-viewer.html Provides functionality to trigger the browser print dialog and communicate with the parent window to initiate a PDF download via postMessage. ```javascript document.getElementById('print').addEventListener('click', () => { if (!pdfDocument) return; window.print(); }); document.getElementById('download').addEventListener('click', async () => { const data = await getPDFData(); if (data) { window.parent.postMessage({ type: 'downloadPDF', data: Array.from(data) }, '*'); } }); ``` -------------------------------- ### Initialize PDF Viewer and Form Handling with PDF.js Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/public/pdfjs-viewer/form-viewer.html This JavaScript code initializes the PDF.js library, sets up the viewer, link service, and scripting manager for handling PDF documents and XFA forms. It configures the worker source and event listeners for loading PDFs and retrieving data. ```javascript import * as pdfjsLib from './pdf.mjs'; import { EventBus, PDFViewer, PDFLinkService, PDFScriptingManager } from './pdf_viewer.mjs'; pdfjsLib.GlobalWorkerOptions.workerSrc = './pdf.worker.mjs'; const eventBus = new EventBus(); const linkService = new PDFLinkService({ eventBus }); const scriptingManager = new PDFScriptingManager({ eventBus, sandboxBundleSrc: './pdf.sandbox.mjs', docProperties: async (pdfDocument) => { return { title: '', author: '', subject: '', keywords: '', creator: '', producer: '', creationDate: null, modDate: null }; } }); const pdfViewer = new PDFViewer({ container: document.getElementById('viewerContainer'), viewer: document.getElementById('viewer'), eventBus, linkService, scriptingManager, renderer: 'canvas' }); linkService.setViewer(pdfViewer); scriptingManager.setViewer(pdfViewer); let pdfDocument = null; let currentScale = 1.0; ``` -------------------------------- ### Apache Configuration for WASM Serving Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/DEPLOYMENT.md Apache configuration using mod_deflate for on-the-fly compression and setting the correct MIME type for .wasm files. This ensures WASM files are served efficiently and with the correct content type. ```apache AddType application/wasm .wasm ``` -------------------------------- ### Load and Process PDF Documents with PDF.js Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/public/pdfjs-viewer/form-viewer.html This function loads a PDF document using PDF.js, enabling XFA form support. It then sets up the document for the viewer, link service, and scripting manager, and updates the UI to display the total number of pages. It also includes error handling and communication with a parent window. ```javascript async function loadPDF(data) { try { const loadingTask = pdfjsLib.getDocument({ data, enableXfa: true }); pdfDocument = await loadingTask.promise; await scriptingManager.setDocument(pdfDocument); pdfViewer.setDocument(pdfDocument); linkService.setDocument(pdfDocument); document.getElementById('numPages').textContent = pdfDocument.numPages; document.getElementById('pageNumber').max = pdfDocument.numPages; window.parent.postMessage({ type: 'pdfLoaded', numPages: pdfDocument.numPages }, '*'); } catch (error) { console.error('Error loading PDF:', error); window.parent.postMessage({ type: 'error', message: error.message }, '*'); } } ``` -------------------------------- ### Run Project Linting Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/README.md Lints the project code using ESLint to enforce code quality and style consistency. This command helps identify potential errors and maintain code standards. ```bash npm run lint ``` -------------------------------- ### Implement PDF Viewer Navigation and Zoom Controls Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/public/pdfjs-viewer/form-viewer.html Handles UI events for page navigation and zoom adjustments. It updates the pdfViewer instance state based on user input and synchronizes the scale select dropdown. ```javascript document.getElementById('pageNumber').addEventListener('change', (e) => { const pageNum = parseInt(e.target.value); if (pageNum >= 1 && pageNum <= pdfDocument?.numPages) { pdfViewer.currentPageNumber = pageNum; } }); document.getElementById('zoomIn').addEventListener('click', () => { currentScale = Math.min(currentScale + 0.1, 3.0); pdfViewer.currentScale = currentScale; document.getElementById('scaleSelect').value = currentScale.toFixed(2); }); document.getElementById('zoomOut').addEventListener('click', () => { currentScale = Math.max(currentScale - 0.1, 0.1); pdfViewer.currentScale = currentScale; document.getElementById('scaleSelect').value = currentScale.toFixed(2); }); ``` -------------------------------- ### Apache Configuration for PDFCraft (.htaccess) Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/DEPLOYMENT.md This .htaccess file configures Apache to serve the PDFCraft application. It enables the rewrite engine for serving HTML files without extensions, sets the MIME type for WASM files, configures caching for static assets, and applies essential security headers, including those required for SharedArrayBuffer. ```apache # Enable rewrite engine RewriteEngine On # Serve HTML files without extension RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([^\]+)$ $1.html [NC,L] # WASM MIME type AddType application/wasm .wasm # Cache static assets Header set Cache-Control "public, max-age=31536000, immutable" # Security headers Header set X-Content-Type-Options "nosniff" Header set X-Frame-Options "SAMEORIGIN" Header set X-XSS-Protection "1; mode=block" Header set Referrer-Policy "strict-origin-when-cross-origin" Header set Permissions-Policy "camera=(), microphone=(), geolocation=()" # Required for SharedArrayBuffer (LibreOffice WASM pthreads) Header set Cross-Origin-Opener-Policy "same-origin" Header set Cross-Origin-Embedder-Policy "require-corp" Header set Cross-Origin-Resource-Policy "cross-origin" ``` -------------------------------- ### Firebase Hosting Configuration Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/DEPLOYMENT.md JSON configuration for firebase.json, defining public directories, clean URL settings, and security headers for static assets. ```json { "hosting": { "public": "out", "ignore": ["firebase.json", "**/.*", "**/node_modules/**"], "cleanUrls": true, "trailingSlash": true, "headers": [ { "source": "**/*.@(js|css|woff|woff2|ttf|eot|ico|jpg|jpeg|png|gif|svg|webp|avif|wasm)", "headers": [ { "key": "Cache-Control", "value": "public, max-age=31536000, immutable" } ] }, { "source": "**", "headers": [ { "key": "X-Content-Type-Options", "value": "nosniff" }, { "key": "X-Frame-Options", "value": "SAMEORIGIN" }, { "key": "X-XSS-Protection", "value": "1; mode=block" }, { "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" }, { "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=()" }, { "key": "Cross-Origin-Opener-Policy", "value": "same-origin" }, { "key": "Cross-Origin-Embedder-Policy", "value": "require-corp" }, { "key": "Cross-Origin-Resource-Policy", "value": "cross-origin" } ] } ] } } ``` -------------------------------- ### Nginx Configuration for PDFCraft Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/DEPLOYMENT.md This Nginx configuration sets up a server block to host the PDFCraft application. It includes directives for listening on port 80, setting the document root, enabling gzip compression, defining MIME types for WASM and JavaScript modules, and applying various security headers. It also configures specific caching and header settings for static assets and WASM files. ```nginx server { listen 80; server_name your-domain.com; root /var/www/html; index index.html; # Gzip compression gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml application/wasm; # MIME types for WASM and ES modules types { application/wasm wasm; application/javascript mjs; } # Security headers add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; # Required for SharedArrayBuffer (LibreOffice WASM pthreads) add_header Cross-Origin-Opener-Policy "same-origin" always; add_header Cross-Origin-Embedder-Policy "require-corp" always; add_header Cross-Origin-Resource-Policy "cross-origin" always; # IMPORTANT: Nginx's add_header in a location block overrides ALL # server-level add_header directives. Every location block that uses # add_header must re-include all required security/CORS headers. # Static assets - long cache location ~* \.(ico|jpg|jpeg|png|gif|svg|webp|avif|woff|woff2|ttf|eot|js|css)$ { expires 1y; add_header Cache-Control "public, max-age=31536000, immutable"; add_header X-Content-Type-Options "nosniff" always; add_header Cross-Origin-Opener-Policy "same-origin" always; add_header Cross-Origin-Embedder-Policy "require-corp" always; add_header Cross-Origin-Resource-Policy "cross-origin" always; } # LibreOffice WASM files - gzip_static auto-serves .gz with correct headers # Requires both soffice.wasm and soffice.wasm.gz on disk (postbuild handles this) location /libreoffice-wasm/ { gzip_static on; expires 1y; add_header Cache-Control "public, max-age=31536000, immutable"; types { application/wasm wasm; application/javascript js; application/octet-stream data; } add_header X-Content-Type-Options "nosniff" always; add_header Cross-Origin-Opener-Policy "same-origin" always; add_header Cross-Origin-Embedder-Policy "require-corp" always; add_header Cross-Origin-Resource-Policy "cross-origin" always; } # HTML pages - no cache location / { try_files $uri $uri.html $uri/ =404; add_header Cache-Control "public, max-age=0, must-revalidate"; add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header Cross-Origin-Opener-Policy "same-origin" always; add_header Cross-Origin-Embedder-Policy "require-corp" always; add_header Cross-Origin-Resource-Policy "cross-origin" always; } # 404 page error_page 404 /404.html; } ``` -------------------------------- ### Merge PDF Documents (TypeScript) Source: https://context7.com/pdfcrafttool/pdfcraft/llms.txt Demonstrates how to merge multiple PDF files into a single document using the PDFCraft library. It shows both a convenience function and direct usage of the merge processor, including options for preserving bookmarks and handling progress updates. The output is a downloadable Blob. ```typescript import { mergePDFs, createMergeProcessor } from '@/lib/pdf/processors/merge'; // Using the convenience function const files = [file1, file2, file3]; // Array of File objects const result = await mergePDFs( files, { preserveBookmarks: true, pageOrder: 'sequential' }, (progress, message) => { console.log(`Progress: ${progress}% - ${message}`); } ); if (result.success && result.result) { // Download the merged PDF const url = URL.createObjectURL(result.result as Blob); const link = document.createElement('a'); link.href = url; link.download = result.filename || 'merged.pdf'; link.click(); URL.revokeObjectURL(url); } // Using the processor class directly for more control const processor = createMergeProcessor(); const output = await processor.process( { files, options: { preserveBookmarks: true } }, (progress, message) => updateUI(progress, message) ); // Cancel processing if needed processor.cancel(); ``` -------------------------------- ### Implement HASH_PARAMS Polyfill Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/public/pdfjs-annotation-viewer/web/viewer.html Provides a minimal HASH_PARAMS implementation for the pdfjs-annotation-extension bundle. It parses URL hash parameters to prevent runtime errors in environments where the global object is missing. ```javascript (function () { if (window.HASH_PARAMS) { return; } const hash = window.location.hash || ""; const raw = hash.startsWith("#") ? hash.slice(1) : hash; const params = new URLSearchParams(raw); window.HASH_PARAMS = { get(name) { const v = params.get(name); return v == null ? "" : String(v); }, }; })(); ``` -------------------------------- ### Pull and Run PDFCraft Docker Image Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/README.md Pulls the latest PDFCraft Docker image from GitHub Container Registry and runs it as a detached container, exposing the application on port 8080. ```bash # Pull the latest image docker pull ghcr.io/pdfcrafttool/pdfcraft:latest # Run the container docker run -d -p 8080:80 --name pdfcraft ghcr.io/pdfcrafttool/pdfcraft:latest ``` -------------------------------- ### Handle PDF Load and Save via PostMessage Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/public/pdfjs-viewer/sign-viewer.html Listens for messages from the parent window to load PDF data or trigger a save operation. It uses the postMessage API to communicate document status and binary data back to the parent. ```javascript window.addEventListener('message', async (event) => { if (event.data.type === 'loadPDF') { loadPDF(event.data.data); } else if (event.data.type === 'save') { const data = await pdfDocument.saveDocument(); window.parent.postMessage({ type: 'downloadPDF', data: Array.from(data) }, '*'); } }); ``` -------------------------------- ### Required Headers for WebAssembly Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/DEPLOYMENT.md These headers are crucial for enabling Cross-Origin Isolation, which is required for LibreOffice WASM to function correctly due to its reliance on SharedArrayBuffer. They must be returned on all relevant responses. ```http Cross-Origin-Opener-Policy: same-origin Cross-Origin-Embedder-Policy: require-corp Cross-Origin-Resource-Policy: cross-origin ``` -------------------------------- ### Convert Images to PDF with PDF Craft Source: https://context7.com/pdfcrafttool/pdfcraft/llms.txt Converts various image formats (JPG, PNG, WebP, BMP, TIFF, SVG, HEIC) into a single PDF document. Supports configurable page sizes, orientations, margins, and image scaling. Batch conversion to ZIP archives is also available. ```typescript import { imagesToPDF, imagesToPDFBatch, PAGE_SIZES } from '@/lib/pdf/processors/image-to-pdf'; // Convert multiple images to a single PDF const images = [image1, image2, image3]; // Array of File objects const result = await imagesToPDF( images, { pageSize: 'A4', orientation: 'auto', margin: 36, quality: 0.92, centerImage: true, scaleToFit: true, }, (progress, message) => updateProgress(progress) ); // Fit page size to image dimensions const fitResult = await imagesToPDF(images, { pageSize: 'FIT', margin: 0, }); // Batch mode: create multiple PDFs and package as ZIP const batchResult = await imagesToPDFBatch( images, 10, // images per PDF { pageSize: 'LETTER', orientation: 'portrait' }, (progress, message) => console.log(message) ); if (batchResult.success && batchResult.result) { const { zipBlob, pdfCount, imageCount } = batchResult.result; downloadBlob(zipBlob, 'image_pdfs.zip'); } ``` -------------------------------- ### Configure PDF Viewer Scaling Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/public/pdfjs-viewer/sign-viewer.html Handles the scale selection change event for the PDF viewer. It supports predefined modes like 'auto' or 'page-fit' and custom numeric scales. ```javascript document.getElementById('scaleSelect').addEventListener('change', (e) => { const value = e.target.value; if (value === 'auto' || value === 'page-fit' || value === 'page-width') { pdfViewer.currentScaleValue = value; } else { currentScale = parseFloat(value); pdfViewer.currentScale = currentScale; } }); ``` -------------------------------- ### Decompress WASM Files for Production Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/DEPLOYMENT.md This script decompresses the .gz WASM files to their raw format for the production build. It's executed as a post-build script to ensure production-ready assets. ```javascript node scripts/decompress-wasm.mjs ``` -------------------------------- ### Nginx Configuration for WASM Serving Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/DEPLOYMENT.md Nginx configuration to enable static gzip decompression and set the correct MIME type for WASM files. This allows Nginx to automatically serve the compressed .gz version to capable clients while maintaining the correct Content-Type. ```nginx gzip_static on; AddType application/wasm .wasm; ``` -------------------------------- ### Implement PDF Navigation Controls with PDF.js Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/public/pdfjs-viewer/form-viewer.html This code sets up event listeners for navigation buttons to control the current page of the PDF viewer. It allows users to navigate to the previous and next pages, ensuring the page number stays within the valid range of the document. ```javascript document.getElementById('previousPage').addEventListener('click', () => { if (pdfViewer.currentPageNumber > 1) { pdfViewer.currentPageNumber--; } }); document.getElementById('nextPage').addEventListener('click', () => { if (pdfViewer.currentPageNumber < pdfDocument?.numPages) { pdfViewer.currentPageNumber++; } }); ``` -------------------------------- ### Compress PDF Files with PDFCraft Source: https://context7.com/pdfcrafttool/pdfcraft/llms.txt Reduces PDF file size using algorithms like standard, condense, and photon. It supports configurable quality settings and metadata removal to balance file size and document fidelity. ```typescript import { compressPDF, createCompressProcessor } from '@/lib/pdf/processors/compress'; import type { CompressionQuality, CompressionAlgorithm } from '@/lib/pdf/processors/compress'; // Basic compression with default settings const result = await compressPDF( pdfFile, { algorithm: 'standard', quality: 'medium', removeMetadata: false, optimizeImages: true, removeUnusedObjects: true, }, (progress, message) => setProgress(progress) ); // High compression using photon algorithm (rasterizes pages) const highCompression = await compressPDF(pdfFile, { algorithm: 'photon', quality: 'high', photonDpi: 150, photonFormat: 'jpeg', photonQuality: 85, }); // Check compression results if (result.success) { const { originalSize, compressedSize, compressionRatio } = result.metadata as { originalSize: number; compressedSize: number; compressionRatio: string; }; console.log(`Compressed from ${originalSize} to ${compressedSize} (${compressionRatio})`); } ``` -------------------------------- ### Decompress WASM Files for Development Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/DEPLOYMENT.md This script decompresses the .gz WASM files to their raw format, preparing them for the development environment. It's typically run as a pre-development script. ```javascript node scripts/decompress-wasm-dev.mjs ``` -------------------------------- ### PDF Navigation and Zoom Controls Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/public/pdfjs-viewer/sign-viewer.html Implements event listeners for UI elements to manage page navigation and zoom levels. These functions update the PDFViewer instance state based on user interaction. ```javascript document.getElementById('previousPage').addEventListener('click', () => { if (pdfViewer.currentPageNumber > 1) pdfViewer.currentPageNumber--; }); document.getElementById('zoomIn').addEventListener('click', () => { currentScale = Math.min(currentScale + 0.1, 3.0); pdfViewer.currentScale = currentScale; }); ``` -------------------------------- ### POST /api/pdf/convert/images-to-pdf Source: https://context7.com/pdfcrafttool/pdfcraft/llms.txt Converts a collection of images into a single PDF document or a batch of PDFs. ```APIDOC ## POST /api/pdf/convert/images-to-pdf ### Description Converts images (JPG, PNG, WebP, BMP, TIFF, SVG, HEIC) to PDF with configurable page sizes, orientations, and layout options. ### Method POST ### Endpoint /api/pdf/convert/images-to-pdf ### Parameters #### Request Body - **images** (Array) - Required - Array of image files to convert - **pageSize** (string) - Optional - Page size (e.g., 'A4', 'LETTER', 'FIT') - **orientation** (string) - Optional - 'portrait', 'landscape', or 'auto' - **margin** (number) - Optional - Margin in points - **quality** (number) - Optional - Image quality (0.0 to 1.0) ### Request Example { "pageSize": "A4", "orientation": "auto", "margin": 36, "quality": 0.92 } ### Response #### Success Response (200) - **result** (Blob) - The generated PDF file #### Response Example { "success": true, "result": "[Blob]" } ``` -------------------------------- ### Compress PDF Files Source: https://context7.com/pdfcrafttool/pdfcraft/llms.txt Reduces PDF file size using multiple compression algorithms: standard, condense, and photon. Each algorithm offers different trade-offs between compression ratio and document fidelity. ```APIDOC ## Compress PDF Files ### Description Reduces PDF file size using multiple compression algorithms: standard (coherentpdf), condense (PyMuPDF), and photon (rasterization). Each algorithm offers different trade-offs between compression ratio and document fidelity. ### Method POST (assumed, as it modifies the file) ### Endpoint /pdfcrafttool/pdfcraft/compress ### Parameters #### Request Body - **pdfFile** (File) - Required - The PDF file to compress. - **options** (Object) - Optional - Compression settings. - **algorithm** (string) - Optional - 'standard', 'condense', or 'photon'. Defaults to 'standard'. - **quality** (string) - Optional - 'low', 'medium', or 'high'. Defaults to 'medium'. - **removeMetadata** (boolean) - Optional - Whether to remove metadata. Defaults to false. - **optimizeImages** (boolean) - Optional - Whether to optimize images. Defaults to true. - **removeUnusedObjects** (boolean) - Optional - Whether to remove unused objects. Defaults to true. - **photonDpi** (number) - Optional - DPI for photon compression. Required if algorithm is 'photon'. - **photonFormat** (string) - Optional - Image format for photon compression ('jpeg', 'png'). Defaults to 'jpeg'. - **photonQuality** (number) - Optional - Quality for photon compression (0-100). Defaults to 85. ### Request Example ```typescript const result = await compressPDF( pdfFile, { algorithm: 'standard', quality: 'medium', removeMetadata: false, optimizeImages: true, removeUnusedObjects: true, }, (progress, message) => setProgress(progress) ); ``` ### Response #### Success Response (200) - **success** (boolean) - Indicates if compression was successful. - **metadata** (object) - Contains compression details. - **originalSize** (number) - Original file size in bytes. - **compressedSize** (number) - Compressed file size in bytes. - **compressionRatio** (string) - The ratio of compression (e.g., '50%'). #### Response Example ```json { "success": true, "metadata": { "originalSize": 1024000, "compressedSize": 512000, "compressionRatio": "50%" } } ``` ``` -------------------------------- ### Docker Build Decompression Command Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/DEPLOYMENT.md Command used within a Dockerfile to decompress .gz files. The `gunzip -k` command decompresses the file in place, leaving both the original .gz and the decompressed file. ```bash RUN gunzip -k /website/pdfcraft/libreoffice-wasm/soffice.wasm.gz ``` -------------------------------- ### Batch Processing Hook Source: https://context7.com/pdfcrafttool/pdfcraft/llms.txt Provides a React hook for efficiently processing multiple files concurrently, with features for progress tracking and consolidated ZIP downloads. ```APIDOC ## Batch Processing Hook ### Description React hook for processing multiple files with the same operation, supporting concurrent processing, progress tracking, and ZIP download. ### Method N/A (React Hook) ### Endpoint N/A (Client-side Hook) ### Parameters N/A ### Request Example ```typescript import { useBatchProcessing } from '@/lib/hooks/useBatchProcessing'; function BatchCompressor() { const { /* ... state and methods ... */ } = useBatchProcessing({ maxConcurrent: 2, onFileComplete: (file) => console.log(`Completed: ${file.file.name}`), onAllComplete: (files) => console.log(`All ${files.length} files processed`), onError: (file, error) => console.error(`Error in ${file.file.name}: ${error.message}`), }); const handleProcess = () => { startProcessing(async (file, onProgress) => { const result = await compressPDF( file, { quality: 'medium' }, (progress) => onProgress(progress) ); if (!result.success) throw new Error(result.error?.message); return result.result as Blob; }); }; return (
addFiles(Array.from(e.target.files || []))} /> {completedCount} completed, {errorCount} errors
); } ``` ### Response N/A (Client-side Hook) ``` -------------------------------- ### Synchronize Viewer State with UI Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/public/pdfjs-viewer/form-viewer.html Listens for 'pagechanging' events to update the page number input field and toggle the disabled state of navigation buttons. ```javascript eventBus.on('pagechanging', (evt) => { document.getElementById('pageNumber').value = evt.pageNumber; document.getElementById('previousPage').disabled = evt.pageNumber <= 1; document.getElementById('nextPage').disabled = evt.pageNumber >= pdfDocument?.numPages; }); ``` -------------------------------- ### Next.js Configuration for Unoptimized Images Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/DEPLOYMENT.md Configuration within next.config.js to disable image optimization. This is sometimes necessary for specific image types or when dealing with assets that should not be processed by Next.js's image optimization pipeline. ```javascript images: { unoptimized: true } ``` -------------------------------- ### GitHub Pages DNS Configuration Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/DEPLOYMENT.md DNS record requirements for pointing a custom domain to a GitHub Pages site. ```text Type: CNAME Name: www (or @) Value: your-username.github.io ``` -------------------------------- ### POST /api/pdf/convert/pdf-to-images Source: https://context7.com/pdfcrafttool/pdfcraft/llms.txt Converts PDF pages into image formats like PNG, JPG, or WebP with resolution and layout controls. ```APIDOC ## POST /api/pdf/convert/pdf-to-images ### Description Converts PDF pages to images with configurable resolution and grid layout options. ### Method POST ### Endpoint /api/pdf/convert/pdf-to-images ### Parameters #### Request Body - **pdfFile** (File) - Required - The source PDF file - **format** (string) - Required - Output format (png, jpg, webp, etc.) - **scale** (number) - Optional - Resolution scale factor - **pages** (Array) - Optional - Specific pages to convert ### Request Example { "format": "png", "scale": 2, "pages": [1, 2] } ### Response #### Success Response (200) - **result** (Array) - Array of image blobs #### Response Example { "success": true, "result": "[Array]" } ``` -------------------------------- ### Split PDF by Page Ranges (TypeScript) Source: https://context7.com/pdfcrafttool/pdfcraft/llms.txt Provides functionality to split a PDF document into multiple files based on specified page ranges. It includes utility functions for parsing range strings, creating ranges for splitting every N pages, and deriving ranges from bookmarks. The code handles multiple output files and download operations. ```typescript import { splitPDF, parsePageRanges, createSplitEveryNPages, createSplitByBookmarks, } from '@/lib/pdf/processors/split'; // Split by custom page ranges const result = await splitPDF( pdfFile, { ranges: [ { start: 1, end: 5 }, { start: 6, end: 10 }, { start: 11, end: 15 }, ], outputFormat: 'multiple', }, (progress, message) => console.log(`${progress}%: ${message}`) ); // Parse range string "1-5, 6-10, 15" into PageRange objects const ranges = parsePageRanges('1-5, 6-10, 15', totalPages); // Create ranges to split every 10 pages const rangesEvery10 = createSplitEveryNPages(totalPages, 10); // Create ranges based on bookmarks const { ranges: bookmarkRanges, labels } = createSplitByBookmarks(bookmarks, totalPages); // Handle multiple output files if (result.success && Array.isArray(result.result)) { const blobs = result.result as Blob[]; const filenames = result.metadata?.outputFiles as string[]; blobs.forEach((blob, index) => { downloadBlob(blob, filenames[index]); }); } ``` -------------------------------- ### Convert PDF Pages to Images with PDF Craft Source: https://context7.com/pdfcrafttool/pdfcraft/llms.txt Converts PDF pages into image files (PNG, JPG, WebP, BMP, TIFF). Allows configuration of resolution (scale), quality, background color, and selection of specific pages. Supports a grid layout to combine multiple pages into single images. ```typescript import { pdfToImages, createPDFToImageProcessor } from '@/lib/pdf/processors/pdf-to-image'; // Convert all pages to PNG images const result = await pdfToImages( pdfFile, { format: 'png', quality: 0.92, scale: 2, // 144 DPI (2x of 72 DPI) pages: [], // Empty = all pages backgroundColor: '#ffffff', }, (progress, message) => setProgress(progress) ); // Convert specific pages to JPEG const specificPages = await pdfToImages(pdfFile, { format: 'jpg', quality: 0.85, scale: 3, // 216 DPI for high quality pages: [1, 5, 10], // Only convert these pages }); // Grid layout: combine multiple pages into single images (2x2 grid) const gridResult = await pdfToImages(pdfFile, { format: 'png', scale: 1.5, pageLayout: { preset: '2x2', columns: 2, rows: 2, skipFirstPage: true, // First page rendered alone as cover }, }); // Handle multiple output images if (result.success && Array.isArray(result.result)) { const images = result.result as Blob[]; images.forEach((blob, index) => { downloadBlob(blob, `page_${index + 1}.png`); }); } ``` -------------------------------- ### Retrieve and Save PDF Document Data with PDF.js Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/public/pdfjs-viewer/form-viewer.html This function retrieves the data of the currently loaded PDF document. It checks if the document is a pure XFA form, in which case saving filled data is not supported and a warning is posted. Otherwise, it attempts to save the document data. Error handling is included for potential issues during saving. ```javascript async function getPDFData() { if (!pdfDocument) return null; if (pdfDocument.isPureXfa) { console.warn('Pure XFA form detected - saving with filled data is not supported'); window.parent.postMessage({ type: 'error', message: 'XFA forms cannot be saved with filled data. Please print to PDF instead.' }, '*'); return null; } try { const data = await pdfDocument.saveDocument(); return data; } catch (error) { console.error('Error saving PDF document:', error); window.parent.postMessage({ type: 'error', message: 'Failed to save PDF. This may be an XFA form or protected PDF.' }, '*'); return null; } } ``` -------------------------------- ### Stop Docker Compose Containers Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/README.md Stops and removes all containers, networks, and volumes defined in the Docker Compose file for the PDFCraft project. ```bash docker compose down ``` -------------------------------- ### Handle PDF Page Navigation Events Source: https://github.com/pdfcrafttool/pdfcraft/blob/main/public/pdfjs-viewer/sign-viewer.html Listens for the 'pagechanging' event to update the UI page number input and toggle the enabled state of navigation buttons. ```javascript eventBus.on('pagechanging', (evt) => { document.getElementById('pageNumber').value = evt.pageNumber; document.getElementById('previousPage').disabled = evt.pageNumber <= 1; document.getElementById('nextPage').disabled = evt.pageNumber >= pdfDocument?.numPages; }); ``` -------------------------------- ### FileUploader Component Integration Source: https://context7.com/pdfcrafttool/pdfcraft/llms.txt The FileUploader component provides a drag-and-drop interface for file selection with built-in validation for file types, sizes, and counts. ```APIDOC ## FileUploader Component ### Description A reusable React component for handling file uploads via drag-and-drop, browsing, or clipboard pasting. It supports file validation including MIME types, file size limits, and maximum file counts. ### Parameters #### Props - **accept** (string[]) - Required - Array of allowed MIME types or file extensions. - **multiple** (boolean) - Optional - Whether to allow multiple file selection. - **maxSize** (number) - Optional - Maximum file size in bytes. - **maxFiles** (number) - Optional - Maximum number of files allowed. - **onFilesSelected** (function) - Required - Callback function triggered when files are validated and selected. - **onError** (function) - Optional - Callback function for handling validation errors. ### Implementation Example ```typescript ``` ```