Files
pastel-wasm/CLAUDE.md

309 lines
8.2 KiB
Markdown
Raw Normal View History

# CLAUDE.md
This file provides guidance to Claude Code when working with this repository.
## Project Overview
**pastel-wasm** is a WebAssembly color manipulation library built with Rust. It provides comprehensive color operations directly in the browser with zero network latency.
**Key Stats:**
- Bundle size: 132KB (WASM)
- Language: Rust + WebAssembly
- Target: Modern browsers with WASM support
- Dependencies: Minimal (wasm-bindgen, serde, rand, getrandom)
## Architecture
### Project Structure
```
pastel-wasm/
├── src/
│ ├── lib.rs # Main WASM bindings and exported functions
│ ├── color.rs # Core color type and conversions
│ └── named.rs # Named colors database (148 CSS/X11 colors)
├── pkg/ # Build output (generated by wasm-pack)
│ ├── pastel_wasm.js
│ ├── pastel_wasm.d.ts
│ └── pastel_wasm_bg.wasm
├── Cargo.toml # Rust dependencies and configuration
├── package.json # NPM package configuration
├── README.md # User documentation
└── example.html # Interactive demo
## Color Implementation
### Color Type (`src/color.rs`)
The core `Color` struct represents colors in RGB space (0.0-1.0 range):
```rust
pub struct Color {
pub r: f64,
pub g: f64,
pub b: f64,
pub a: f64,
}
```
**Key Methods:**
- `parse(s: &str)` - Universal color parser (hex, rgb, hsl, named)
- `to_hex()` - Convert to hex string
- `to_hsl()`, `to_hsv()`, `to_lab()`, `to_lch()` - Color space conversions
- `lighten()`, `darken()`, `saturate()`, `desaturate()` - Adjustments
- `rotate_hue()`, `complement()`, `mix()` - Transformations
- `text_color()`, `contrast_ratio()` - Accessibility helpers
- `simulate_protanopia/deuteranopia/tritanopia()` - Color blindness
- `distance_cie76()`, `distance_ciede2000()` - Perceptual distance
### Color Space Conversions
**Implemented color spaces:**
- RGB ↔ HSL (Hue, Saturation, Lightness)
- RGB ↔ HSV (Hue, Saturation, Value)
- RGB → XYZ → Lab (CIELab, perceptually uniform)
- Lab → LCH (Lightness, Chroma, Hue)
**Conversion accuracy:**
- Uses D65 illuminant for XYZ conversions
- Implements proper gamma correction for sRGB
- Perceptually accurate Lab/LCH calculations
### Named Colors (`src/named.rs`)
Contains 148 CSS/X11 named colors as const data:
```rust
pub const NAMED_COLORS: &[NamedColor] = &[
NamedColor { name: "red", hex: "#ff0000" },
// ... 147 more
];
```
## WASM Bindings (`src/lib.rs`)
All exported functions are annotated with `#[wasm_bindgen]`:
**Categories:**
1. **Color Information** - `parse_color()`
2. **Color Manipulation** - `lighten_color()`, `darken_color()`, etc.
3. **Color Generation** - `generate_random_colors()`, `generate_gradient()`, `generate_palette()`
4. **Accessibility** - `get_text_color()`, `simulate_*()`, `calculate_contrast()`
5. **Named Colors** - `get_all_named_colors()`, `search_named_colors()`
6. **Utilities** - `color_distance()`, `version()`
**Return types:**
- Simple functions return `Result<String, JsValue>` (hex colors)
- Complex functions return `Result<JsValue, JsValue>` (serialized objects)
- Uses `serde_wasm_bindgen` for JS ↔ Rust serialization
## Building
### Prerequisites
```bash
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install wasm-pack
cargo install wasm-pack
```
### Build Commands
```bash
# Build for bundler (Webpack, Rollup, Vite)
wasm-pack build --target bundler --out-dir pkg
# Build for web (vanilla JS)
wasm-pack build --target web --out-dir pkg-web
# Build for Node.js
wasm-pack build --target nodejs --out-dir pkg-node
# Build all targets
npm run build:all
```
### Build Configuration
**Cargo.toml optimizations:**
- `opt-level = "s"` - Optimize for size
- `lto = true` - Link-time optimization
- `codegen-units = 1` - Better optimization
- `strip = true` - Remove debug symbols
**wasm-opt flags:**
- `--enable-bulk-memory` - Memory operations
- `--enable-nontrapping-float-to-int` - Modern WASM features
- `-Os` - Optimize for size
## Dependencies
**Core dependencies:**
- `wasm-bindgen = "0.2"` - Rust ↔ JavaScript interop
- `serde = "1.0"` - Serialization framework
- `serde-wasm-bindgen = "0.6"` - JS object serialization
- `rand = "0.8"` - Random number generation
- `getrandom = { version = "0.2", features = ["js"] }` - WASM-compatible RNG
- `js-sys = "0.3"` - JavaScript standard library bindings
- `web-sys = "0.3"` - Web API bindings
- `console_error_panic_hook = "0.1"` - Better panic messages in browser
## Testing
```bash
# Run tests in headless browsers
wasm-pack test --headless --firefox --chrome
# Run tests in specific browser
wasm-pack test --firefox
wasm-pack test --chrome
```
## Publishing
```bash
# Build and test
npm run build
npm test
# Publish to npm
wasm-pack pack
wasm-pack publish
```
## Integration with pastel-ui
The `pastel-ui` Next.js application uses this WASM module instead of the REST API:
**Migration steps:**
1. Install: `npm install pastel-wasm`
2. Import: `import * as pastel from 'pastel-wasm'`
3. Initialize: Call `await pastel.init()` on app load
4. Replace API calls with direct WASM functions
5. Update types (WASM returns simpler structures than API)
**Benefits for pastel-ui:**
- **Performance**: 0ms latency vs 50-200ms API calls
- **Reliability**: No network errors, works offline
- **Cost**: Zero server costs, no rate limiting
- **Privacy**: Color data never leaves the browser
## Development Workflow
### Adding a New Function
1. **Implement in color.rs:**
```rust
impl Color {
pub fn my_new_operation(&self) -> Self {
// implementation
}
}
```
2. **Add WASM binding in lib.rs:**
```rust
#[wasm_bindgen]
pub fn my_new_operation(color: &str) -> Result<String, JsValue> {
let c = Color::parse(color).map_err(|e| JsValue::from_str(&e))?;
Ok(c.my_new_operation().to_hex())
}
```
3. **Rebuild:**
```bash
wasm-pack build --target bundler --out-dir pkg
```
4. **Test in example.html:**
```javascript
const result = pastel.my_new_operation('#ff0099');
```
### Debugging
**Rust errors:**
```bash
# Check for compile errors
cargo check
# Run clippy for lints
cargo clippy
```
**WASM errors:**
- Enable panic hook: `pastel.init()` calls `console_error_panic_hook::set_once()`
- Check browser console for panics
- Use `console.log()` via `web_sys::console::log_1()`
## Performance Considerations
**Fast operations** (< 0.1ms):
- Color parsing
- Simple manipulations (lighten, darken, saturate)
- Color space conversions
- Hex formatting
**Medium operations** (< 1ms):
- Gradient generation (10 steps)
- Palette generation
- Color distance calculations
**Memory:**
- Each Color instance: 32 bytes (4 × f64)
- Named colors array: ~10KB (static data)
- WASM memory grows dynamically as needed
## Common Issues
### Build Fails with "errno not supported"
**Cause**: Using pastel library directly (has CLI dependencies)
**Solution**: Use custom color implementation (already done)
### wasm-opt validation errors
**Cause**: Missing WASM features
**Solution**: Add flags in Cargo.toml:
```toml
[package.metadata.wasm-pack.profile.release]
wasm-opt = ["-Os", "--enable-mutable-globals", "--enable-bulk-memory", "--enable-nontrapping-float-to-int"]
```
### Random number generation fails in browser
**Cause**: Missing JS feature flag for getrandom
**Solution**: Add to Cargo.toml:
```toml
getrandom = { version = "0.2", features = ["js"] }
```
## Future Enhancements
### Planned Features
- [ ] More color harmony schemes (square, split, analogous)
- [ ] Color palettes from images (requires image parsing)
- [ ] CMYK color space support
- [ ] Color name lookup (closest named color)
- [ ] Gradient interpolation in different color spaces (Lab, LCH)
- [ ] Batch processing optimizations
### Optimization Opportunities
- [ ] SIMD operations for batch processing
- [ ] Lazy loading of named colors
- [ ] Memoization of expensive calculations
- [ ] WebWorker support for heavy operations
## Resources
- [wasm-bindgen Book](https://rustwasm.github.io/wasm-bindgen/)
- [Color Science](https://en.wikipedia.org/wiki/CIE_1931_color_space)
- [CIEDE2000 Algorithm](https://en.wikipedia.org/wiki/Color_difference#CIEDE2000)
- [WCAG Contrast](https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html)
---
**Project Status**: Production-ready
**Last Updated**: 2025-01-17