JavaScript SDK
JavaScript SDK
Section titled “JavaScript SDK”The official JavaScript SDK for Splinterpic provides a simple, type-safe way to interact with the API.
Installation
Section titled “Installation”Using npm
Section titled “Using npm”npm install @splinterpic/sdkUsing yarn
Section titled “Using yarn”yarn add @splinterpic/sdkUsing pnpm
Section titled “Using pnpm”pnpm add @splinterpic/sdkQuick Start
Section titled “Quick Start”Basic Usage
Section titled “Basic Usage”import { SplinterpicClient } from '@splinterpic/sdk';
const client = new SplinterpicClient({ baseUrl: 'https://your-worker.workers.dev'});
// Generate an imageconst image = await client.generate({ prompt: 'A beautiful mountain landscape at sunset', model: '@cf/black-forest-labs/flux-1-schnell'});
console.log('Image URL:', image.r2_url);With TypeScript
Section titled “With TypeScript”import { SplinterpicClient, type GenerateImageRequest } from '@splinterpic/sdk';
const client = new SplinterpicClient({ baseUrl: 'https://your-worker.workers.dev'});
const request: GenerateImageRequest = { prompt: 'A beautiful mountain landscape at sunset', model: '@cf/black-forest-labs/flux-1-schnell'};
const image = await client.generate(request);Reference Implementation
Section titled “Reference Implementation”Until the official SDK is published, use this reference implementation:
class SplinterpicClient { constructor(config) { this.baseUrl = config.baseUrl; this.defaultModel = config.defaultModel || '@cf/black-forest-labs/flux-1-schnell'; }
async request(endpoint, options = {}) { const url = `${this.baseUrl}${endpoint}`; const response = await fetch(url, { ...options, headers: { 'Content-Type': 'application/json', ...options.headers } });
if (!response.ok) { const error = await response.json().catch(() => ({ error: 'Request failed' })); throw new Error(error.error || `HTTP ${response.status}`); }
return response.json(); }
// Generate a new image async generate({ prompt, model, template_id }) { return this.request('/api/generate', { method: 'POST', body: JSON.stringify({ prompt, model: model || this.defaultModel, template_id }) }); }
// List images async listImages({ limit = 20, offset = 0 } = {}) { return this.request(`/api/images?limit=${limit}&offset=${offset}`); }
// Get a specific image async getImage(imageId) { return this.request(`/api/images/${imageId}`); }
// Delete an image async deleteImage(imageId) { return this.request(`/api/images/${imageId}`, { method: 'DELETE' }); }
// List collections async listCollections() { return this.request('/api/collections'); }
// Create a collection async createCollection({ name, description }) { return this.request('/api/collections', { method: 'POST', body: JSON.stringify({ name, description }) }); }
// Get collection details async getCollection(collectionId) { return this.request(`/api/collections/${collectionId}`); }
// List images in a collection async getCollectionImages(collectionId) { return this.request(`/api/collections/${collectionId}/images`); }
// Delete a collection async deleteCollection(collectionId) { return this.request(`/api/collections/${collectionId}`, { method: 'DELETE' }); }
// List available models async listModels() { return this.request('/api/models'); }
// Get model details async getModel(modelId) { return this.request(`/api/models/${encodeURIComponent(modelId)}`); }
// Get usage analytics async getUsageAnalytics() { return this.request('/api/analytics/usage'); }
// Get cost analytics async getCostAnalytics() { return this.request('/api/analytics/costs'); }}
// Export for useexport { SplinterpicClient };Usage Examples
Section titled “Usage Examples”Generate Images
Section titled “Generate Images”const client = new SplinterpicClient({ baseUrl: 'https://your-worker.workers.dev'});
// Single imageconst image = await client.generate({ prompt: 'A futuristic city with flying cars', model: '@cf/black-forest-labs/flux-1-schnell'});
console.log(image);// {// id: 'img_abc123',// r2_url: 'https://...',// created_at: '2024-01-15T10:30:00.000Z'// }Batch Generation
Section titled “Batch Generation”const prompts = [ 'Mountain landscape at sunrise', 'Ocean waves during golden hour', 'Forest path in autumn'];
const images = await Promise.all( prompts.map(prompt => client.generate({ prompt })));
console.log(`Generated ${images.length} images`);List and Filter Images
Section titled “List and Filter Images”// Get first 50 imagesconst { images, pagination } = await client.listImages({ limit: 50, offset: 0});
console.log(`Found ${pagination.total} images`);
// Paginate through all imagesasync function getAllImages() { const allImages = []; let offset = 0; const limit = 100;
while (true) { const { images, pagination } = await client.listImages({ limit, offset }); allImages.push(...images);
if (!pagination.has_more) break; offset += limit; }
return allImages;}Manage Collections
Section titled “Manage Collections”// Create a collectionconst collection = await client.createCollection({ name: 'Marketing Campaign 2024', description: 'Q1 social media assets'});
// Add images to collection (note: requires additional endpoint implementation)// This is a placeholder for future functionality// await client.addImageToCollection(collection.id, imageId);
// List all collectionsconst collections = await client.listCollections();
// Get collection detailsconst details = await client.getCollection(collection.id);
// Delete a collectionawait client.deleteCollection(collection.id);Work with Models
Section titled “Work with Models”// List all available modelsconst models = await client.listModels();
models.forEach(model => { console.log(`${model.name}: $${model.cost_per_image}/image`);});
// Get specific model detailsconst fluxModel = await client.getModel('@cf/black-forest-labs/flux-1-schnell');console.log(fluxModel);Track Analytics
Section titled “Track Analytics”// Get usage statisticsconst usage = await client.getUsageAnalytics();console.log(`Total images generated: ${usage.total_images}`);
// Get cost analyticsconst costs = await client.getCostAnalytics();console.log(`Total cost: $${costs.total_cost}`);console.log(`Average per image: $${costs.average_cost}`);Error Handling
Section titled “Error Handling”Basic Error Handling
Section titled “Basic Error Handling”try { const image = await client.generate({ prompt: 'A beautiful landscape', model: '@cf/black-forest-labs/flux-1-schnell' });} catch (error) { console.error('Generation failed:', error.message);}Advanced Error Handling
Section titled “Advanced Error Handling”async function generateWithRetry(prompt, maxRetries = 3) { for (let i = 0; i < maxRetries; i++) { try { return await client.generate({ prompt }); } catch (error) { if (i === maxRetries - 1) throw error;
console.log(`Retry ${i + 1}/${maxRetries}...`); await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1))); } }}
const image = await generateWithRetry('A beautiful landscape');TypeScript Support
Section titled “TypeScript Support”Full TypeScript definitions:
interface SplinterpicConfig { baseUrl: string; defaultModel?: string;}
interface GenerateImageRequest { prompt: string; model?: string; template_id?: string;}
interface Image { id: string; prompt: string; model: string; r2_key: string; r2_url: string; width: number; height: number; created_at: string; user_id: string; cost: number; is_deleted: boolean;}
interface ListImagesResponse { images: Image[]; pagination: { limit: number; offset: number; total: number; has_more: boolean; };}
interface Collection { id: string; name: string; description: string; created_at: string; user_id: string;}
interface Model { id: string; name: string; description: string; cost_per_image: number; is_recommended: boolean;}
declare class SplinterpicClient { constructor(config: SplinterpicConfig);
generate(request: GenerateImageRequest): Promise<Image>; listImages(options?: { limit?: number; offset?: number }): Promise<ListImagesResponse>; getImage(imageId: string): Promise<Image>; deleteImage(imageId: string): Promise<void>;
listCollections(): Promise<{ collections: Collection[] }>; createCollection(data: { name: string; description: string }): Promise<Collection>; getCollection(collectionId: string): Promise<Collection>; getCollectionImages(collectionId: string): Promise<{ images: Image[] }>; deleteCollection(collectionId: string): Promise<void>;
listModels(): Promise<{ models: Model[] }>; getModel(modelId: string): Promise<Model>;
getUsageAnalytics(): Promise<any>; getCostAnalytics(): Promise<any>;}
export { SplinterpicClient };export type { SplinterpicConfig, GenerateImageRequest, Image, ListImagesResponse, Collection, Model};React Integration
Section titled “React Integration”React Hook
Section titled “React Hook”import { useState, useCallback } from 'react';import { SplinterpicClient } from './splinterpic-client';
const client = new SplinterpicClient({ baseUrl: process.env.REACT_APP_API_URL});
function useSplinterpic() { const [loading, setLoading] = useState(false); const [error, setError] = useState(null);
const generate = useCallback(async (prompt) => { setLoading(true); setError(null);
try { const image = await client.generate({ prompt }); return image; } catch (err) { setError(err.message); throw err; } finally { setLoading(false); } }, []);
return { generate, loading, error };}
// Usage in componentfunction ImageGenerator() { const { generate, loading, error } = useSplinterpic(); const [image, setImage] = useState(null);
const handleGenerate = async () => { const result = await generate('A beautiful mountain landscape'); setImage(result); };
return ( <div> <button onClick={handleGenerate} disabled={loading}> {loading ? 'Generating...' : 'Generate Image'} </button> {error && <p>Error: {error}</p>} {image && <img src={image.r2_url} alt={image.prompt} />} </div> );}Next.js API Route
Section titled “Next.js API Route”import { SplinterpicClient } from '@/lib/splinterpic-client';
const client = new SplinterpicClient({ baseUrl: process.env.SPLINTERPIC_API_URL});
export default async function handler(req, res) { if (req.method !== 'POST') { return res.status(405).json({ error: 'Method not allowed' }); }
try { const { prompt } = req.body; const image = await client.generate({ prompt }); res.status(200).json(image); } catch (error) { res.status(500).json({ error: error.message }); }}Node.js Server Example
Section titled “Node.js Server Example”import express from 'express';import { SplinterpicClient } from './splinterpic-client.js';
const app = express();const client = new SplinterpicClient({ baseUrl: process.env.SPLINTERPIC_API_URL});
app.use(express.json());
app.post('/generate', async (req, res) => { try { const { prompt } = req.body; const image = await client.generate({ prompt }); res.json(image); } catch (error) { res.status(500).json({ error: error.message }); }});
app.listen(3000, () => { console.log('Server running on port 3000');});Next Steps
Section titled “Next Steps”- Python SDK - Use Splinterpic with Python Python docs →
- API Reference - Explore the REST API directly API docs →
- React Integration - Build React apps with Splinterpic React guide →
- Next.js Integration - Use Splinterpic in Next.js apps Next.js guide →