soroban-abacus-flashcards/client/node/API.md

259 lines
6.0 KiB
Markdown

# Soroban Flashcard Generator - Node.js API Documentation
## Installation
```bash
npm install python-shell
```
## Basic Usage
```typescript
import { SorobanGenerator } from './soroban-generator-bridge';
const generator = new SorobanGenerator();
const result = await generator.generate({
range: '0-99',
cardsPerPage: 6
});
```
## API Reference
### `SorobanGenerator`
The main class for generating flashcards from Node.js/TypeScript.
#### Constructor
```typescript
new SorobanGenerator(projectRoot?: string)
```
- `projectRoot` (optional): Path to the soroban-abacus-flashcards directory. Defaults to `../../` from the module location.
#### Methods
##### `generate(config: FlashcardConfig): Promise<FlashcardResult>`
Generate flashcards with the specified configuration.
**Parameters:**
- `config`: Configuration object (see FlashcardConfig below)
**Returns:** Promise resolving to:
```typescript
{
pdf: string; // Base64 encoded PDF
count: number; // Number of flashcards generated
numbers: number[]; // Array of numbers (limited to first 100)
}
```
##### `generateBuffer(config: FlashcardConfig): Promise<Buffer>`
Generate flashcards and return as Node.js Buffer.
**Parameters:**
- `config`: Configuration object
**Returns:** Promise resolving to Buffer containing PDF data
##### `initialize(): Promise<void>`
Initialize a persistent Python process for better performance when generating multiple PDFs.
##### `close(): Promise<void>`
Clean up the persistent Python process.
### Configuration Interface
```typescript
interface FlashcardConfig {
// Required
range: string; // e.g., "0-99" or "1,2,5,10"
// Optional
step?: number; // Increment (default: 1)
cardsPerPage?: number; // 1-30+ (default: 6)
paperSize?: 'us-letter' | 'a4' | 'a3' | 'a5';
orientation?: 'portrait' | 'landscape';
margins?: {
top?: string; // e.g., "0.5in"
bottom?: string;
left?: string;
right?: string;
};
gutter?: string; // Space between cards (default: "5mm")
shuffle?: boolean; // Randomize order
seed?: number; // Random seed for deterministic shuffle
showCutMarks?: boolean; // Show cutting guides
showRegistration?: boolean; // Show alignment marks
fontFamily?: string; // Font name (default: "DejaVu Sans")
fontSize?: string; // Font size (default: "48pt")
columns?: string | number; // "auto" or specific number
showEmptyColumns?: boolean;
hideInactiveBeads?: boolean;
beadShape?: 'diamond' | 'circle' | 'square';
colorScheme?: 'monochrome' | 'place-value' | 'heaven-earth' | 'alternating';
coloredNumerals?: boolean; // Color numerals to match beads
scaleFactor?: number; // 0.1 to 1.0 (default: 0.9)
}
```
## Examples
### Basic Generation
```typescript
const generator = new SorobanGenerator();
// Simple 0-9 flashcards
const result = await generator.generate({
range: '0-9'
});
```
### Skip Counting
```typescript
// Count by 5s from 0 to 100
const result = await generator.generate({
range: '0-100',
step: 5,
cardsPerPage: 12
});
```
### Educational Colors
```typescript
// Place-value coloring for learning
const result = await generator.generate({
range: '0-999',
colorScheme: 'place-value',
coloredNumerals: true,
showCutMarks: true
});
```
### Express.js Route
```typescript
app.post('/api/flashcards', async (req, res) => {
try {
const generator = new SorobanGenerator();
const config = {
range: req.body.range || '0-9',
cardsPerPage: req.body.cardsPerPage || 6,
colorScheme: req.body.colorScheme || 'monochrome',
...req.body
};
const result = await generator.generate(config);
if (req.query.format === 'json') {
// Return metadata
res.json({
count: result.count,
numbers: result.numbers
});
} else {
// Return PDF
const pdfBuffer = Buffer.from(result.pdf, 'base64');
res.contentType('application/pdf');
res.setHeader('Content-Disposition', 'attachment; filename=flashcards.pdf');
res.send(pdfBuffer);
}
} catch (error) {
res.status(500).json({ error: error.message });
}
});
```
### Next.js API Route
```typescript
// pages/api/flashcards.ts
import { NextApiRequest, NextApiResponse } from 'next';
import { SorobanGenerator } from '@/lib/soroban-generator-bridge';
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}
try {
const generator = new SorobanGenerator();
const result = await generator.generate(req.body);
const pdfBuffer = Buffer.from(result.pdf, 'base64');
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', 'attachment; filename=flashcards.pdf');
res.send(pdfBuffer);
} catch (error) {
res.status(500).json({ error: error.message });
}
}
```
### Performance Optimization
For generating multiple PDFs, use persistent mode:
```typescript
const generator = new SorobanGenerator();
// Initialize once
await generator.initialize();
// Generate multiple PDFs quickly
for (const config of configs) {
const result = await generator.generate(config);
// Process result...
}
// Clean up when done
await generator.close();
```
## Requirements
- Node.js 14+
- Python 3.8+
- Typst (installed via `brew install typst`)
- qpdf (optional, for PDF optimization)
## Error Handling
The generator will throw errors for:
- Missing Python installation
- Missing Typst installation
- Invalid configuration
- Typst compilation errors
Always wrap calls in try/catch blocks:
```typescript
try {
const result = await generator.generate(config);
} catch (error) {
console.error('Generation failed:', error.message);
}
```
## TypeScript Types
All interfaces and types are included in the module. Import them as needed:
```typescript
import {
SorobanGenerator,
FlashcardConfig,
FlashcardResult
} from './soroban-generator-bridge';
```