Files
pastel-wasm/CLAUDE.md
Sebastian Krüger de18e007a6
Some checks failed
CI / test (push) Failing after 10m13s
Build and Publish to npm / build-and-publish (push) Has been cancelled
feat: initial release of pastel-wasm v0.1.0
🎨 WebAssembly color manipulation library

Features:
-  Color parsing (hex, rgb, hsl, named colors)
- 🎨 Color manipulation (lighten, darken, saturate, desaturate)
- 🌈 Color generation (random, gradients, palettes)
-  Accessibility (colorblind simulation, contrast, WCAG)
- 📏 Color distance (CIE76, CIEDE2000)
- 🎯 Color spaces (RGB, HSL, HSV, Lab, LCH)
- 🏷️  148 CSS/X11 named colors

Bundle size: 132KB
Performance: ~0.1ms per operation

🤖 Generated with Claude Code (https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 07:28:46 +01:00

309 lines
8.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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