From a02285289ad4c88072d25c7fe44342f29c86c3ba Mon Sep 17 00:00:00 2001 From: Thomas Hallock Date: Sun, 14 Sep 2025 17:55:54 -0500 Subject: [PATCH] fix: update bridge generator interface to support SVG format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added format and mode parameters to FlashcardConfig interface to properly support SVG generation through the existing Python bridge. Updated web app to use SorobanGeneratorBridge instead of basic generator. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- apps/web/src/app/api/preview/route.ts | 62 +++---------------- .../node/src/soroban-generator-bridge.ts | 5 +- 2 files changed, 12 insertions(+), 55 deletions(-) diff --git a/apps/web/src/app/api/preview/route.ts b/apps/web/src/app/api/preview/route.ts index 5c3faeef..095c25b8 100644 --- a/apps/web/src/app/api/preview/route.ts +++ b/apps/web/src/app/api/preview/route.ts @@ -1,56 +1,9 @@ import { NextRequest, NextResponse } from 'next/server' -import { spawn } from 'child_process' +import { SorobanGeneratorBridge } from '@soroban/core' import path from 'path' -// Initialize generator with correct absolute path to packages/core -const corePackagePath = path.resolve(process.cwd(), '../../packages/core') - -// Function to call Python bridge directly for SVG generation -async function generateSVGFromPython(config: any): Promise { - return new Promise((resolve, reject) => { - const pythonProcess = spawn('python3', [path.join(corePackagePath, 'src/bridge.py')], { - cwd: corePackagePath, - stdio: ['pipe', 'pipe', 'pipe'] - }) - - let stdout = '' - let stderr = '' - - pythonProcess.stdout.on('data', (data) => { - stdout += data.toString() - }) - - pythonProcess.stderr.on('data', (data) => { - stderr += data.toString() - }) - - pythonProcess.on('close', (code) => { - if (code !== 0) { - reject(new Error(`Python process failed with code ${code}: ${stderr}`)) - return - } - - try { - const result = JSON.parse(stdout.trim()) - if (result.error) { - reject(new Error(result.error)) - } else { - resolve(result.pdf) // This contains the SVG content when format=svg - } - } catch (error) { - reject(new Error(`Failed to parse Python output: ${error}`)) - } - }) - - pythonProcess.on('error', (error) => { - reject(new Error(`Failed to start Python process: ${error}`)) - }) - - // Send config to Python bridge - pythonProcess.stdin.write(JSON.stringify(config) + '\n') - pythonProcess.stdin.end() - }) -} +// Initialize generator (let it figure out its own path) +const generator = new SorobanGeneratorBridge() export async function POST(request: NextRequest) { try { @@ -93,14 +46,15 @@ export async function POST(request: NextRequest) { beadShape: previewConfig.beadShape || 'diamond', colorScheme: previewConfig.colorScheme || 'place-value', hideInactiveBeads: previewConfig.hideInactiveBeads || false, - scaleFactor: 4.0 // Larger scale for preview visibility + scaleFactor: 4.0, // Larger scale for preview visibility + range: number.toString() // Bridge needs range parameter } console.log(`🔍 Generating single-card SVG for number ${number}`) - const svgContent = await generateSVGFromPython(singleCardConfig) - console.log(`✅ Generated single-card SVG for ${number}, length: ${svgContent.length}`) + const result = await generator.generate(singleCardConfig) + console.log(`✅ Generated single-card SVG for ${number}, length: ${result.pdf.length}`) samples.push({ number, - front: svgContent, + front: result.pdf, // Contains SVG content when format=svg back: number.toString() }) } catch (error) { diff --git a/packages/core/client/node/src/soroban-generator-bridge.ts b/packages/core/client/node/src/soroban-generator-bridge.ts index e46d9736..d1c4654d 100644 --- a/packages/core/client/node/src/soroban-generator-bridge.ts +++ b/packages/core/client/node/src/soroban-generator-bridge.ts @@ -32,10 +32,13 @@ export interface FlashcardConfig { colorScheme?: 'monochrome' | 'place-value' | 'heaven-earth' | 'alternating'; coloredNumerals?: boolean; scaleFactor?: number; + format?: 'pdf' | 'svg'; + mode?: 'single-card' | 'flashcards'; + number?: number; } export interface FlashcardResult { - pdf: string; // base64 encoded + pdf: string; // base64 encoded PDF or SVG content (depending on format) count: number; numbers: number[]; }