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

8.2 KiB
Raw Blame 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:

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

# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Install wasm-pack
cargo install wasm-pack

Build Commands

# 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

# 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

# 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:
impl Color {
    pub fn my_new_operation(&self) -> Self {
        // implementation
    }
}
  1. Add WASM binding in lib.rs:
#[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())
}
  1. Rebuild:
wasm-pack build --target bundler --out-dir pkg
  1. Test in example.html:
const result = pastel.my_new_operation('#ff0099');

Debugging

Rust errors:

# 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:

[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:

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


Project Status: Production-ready Last Updated: 2025-01-17