# Utils

Import these from `@grafloria/renderer`.

## Functions

### `applyNodePreset`

Apply a preset to a node

```ts
function applyNodePreset(node: NodeModel, preset: typeof AnimationPresets.NODE[keyof typeof AnimationPresets.NODE]): NodeModel
```

**Parameters**

- `node`: Node to apply preset to
- `preset`: Preset configuration

**Returns** Modified node (mutation)

### `applyWorkflowPreset`

Apply a workflow preset to a node

```ts
function applyWorkflowPreset(
  node: NodeModel,
  preset: typeof AnimationPresets.WORKFLOW[keyof typeof AnimationPresets.WORKFLOW]
): NodeModel
```

**Parameters**

- `node`: Node to apply preset to
- `preset`: Workflow preset configuration

**Returns** Modified node (mutation)

### `buildAnimationClass`

Build animation class string from individual parts

```ts
function buildAnimationClass(...parts: (string | undefined | null | false)[]): string
```

**Parameters**

- `parts`: Array of class name parts (filters out empty/undefined)

**Returns** Space-separated class string

### `calculateAnimationDuration`

Calculate animation duration based on speed setting

```ts
function calculateAnimationDuration(
  baseSpeed: 'slow' | 'normal' | 'fast' | undefined,
  baseDuration: number = 1
): number
```

**Parameters**

- `baseSpeed`: Base animation speed ('slow' | 'normal' | 'fast')
- `baseDuration`: Base duration in seconds (default: 1)

**Returns** Duration in seconds

### `cancelAnimFrame`

Cancel animation frame wrapper with fallback

```ts
function cancelAnimFrame(id: number): void
```

**Parameters**

- `id`: Request ID to cancel

### `canCoexist`

Check if two animations can coexist
Some animations can run simultaneously (e.g., border + status)

```ts
function canCoexist(a: AnimationDescriptor, b: AnimationDescriptor): boolean
```

### `createAnimationCustomProperties`

Create CSS custom properties object for animation

```ts
function createAnimationCustomProperties(options: {
  duration?: number;
  strokeWidth?: number;
  color?: string;
  glowColor?: string;
}): Record<string, string>
```

**Parameters**

- `options`: Animation options

**Returns** Object with CSS custom properties

### `createLinkAnimation`

Create link animation configuration

```ts
function createLinkAnimation(
  type: 'marching-ants' | 'flow' | 'pulse' | 'none',
  options: {
    speed?: 'slow' | 'normal' | 'fast';
    direction?: 'forward' | 'reverse';
    duration?: number;
  } = {}
): LinkAnimation
```

**Parameters**

- `type`: Animation type
- `options`: Additional options

**Returns** LinkAnimation object

### `createPriorityResolver`

Create a priority resolver with default configuration

```ts
function createPriorityResolver(
  config?: Partial<PriorityResolverConfig>
): AnimationPriorityResolver
```

### `debounce`

Debounce function for performance optimization
Useful for animation updates during resize/scroll

```ts
function debounce<T extends (...args: any[]) => any>(
  func: T,
  wait: number
): (...args: Parameters<T>) => void
```

**Parameters**

- `func`: Function to debounce
- `wait`: Wait time in milliseconds

**Returns** Debounced function

### `generateGradientBorderCSS`

Generate dynamic CSS for gradient border animation

```ts
function generateGradientBorderCSS(colors: string[], duration: number = 3): string
```

**Parameters**

- `colors`: Array of gradient colors
- `duration`: Animation duration in seconds

**Returns** CSS string for gradient animation

### `getCoexistingAnimations`

Get all animations that can coexist together
Returns a set of compatible animations

```ts
function getCoexistingAnimations(
  animations: AnimationDescriptor[]
): AnimationDescriptor[]
```

### `getDefaultPriority`

Get default priority for an animation descriptor

```ts
function getDefaultPriority(descriptor: AnimationDescriptor): number
```

### `getLinkAnimationFromPreset`

Get link animation from a preset

```ts
function getLinkAnimationFromPreset(
  preset: typeof AnimationPresets.WORKFLOW[keyof typeof AnimationPresets.WORKFLOW] |
          typeof AnimationPresets.ETL[keyof typeof AnimationPresets.ETL]
): LinkAnimation
```

**Parameters**

- `preset`: Preset with link configuration

**Returns** Link animation configuration

### `getOptimalAnimationSettings`

Get optimal animation settings based on browser performance

```ts
function getOptimalAnimationSettings(): {
  maxAnimatedEdges: number;
  maxAnimatedNodes: number;
  preferredAnimationType: 'simple' | 'complex';
}
```

**Returns** Recommended animation settings

### `isValidAnimationType`

Validate animation type

```ts
function isValidAnimationType(
  type: any
): type is 'marching-ants' | 'flow' | 'pulse' | 'none'
```

**Parameters**

- `type`: Animation type to validate

**Returns** Whether the type is valid

### `isValidBorderAnimationType`

Validate border animation type

```ts
function isValidBorderAnimationType(
  type: any
): type is 'gradient' | 'pulse' | 'breathe' | 'shimmer' | 'none'
```

**Parameters**

- `type`: Border animation type to validate

**Returns** Whether the type is valid

### `isValidStatus`

Validate status type

```ts
function isValidStatus(
  status: any
): status is 'idle' | 'pending' | 'running' | 'completed' | 'error' | 'warning'
```

**Parameters**

- `status`: Status to validate

**Returns** Whether the status is valid

### `measureAnimationFPS`

Measure animation FPS (for debugging/performance monitoring)

```ts
function measureAnimationFPS(duration: number = 1000): Promise<number>
```

**Parameters**

- `duration`: Duration to measure in milliseconds

**Returns** Promise that resolves to average FPS

### `msToSeconds`

Convert animation duration from milliseconds to seconds

```ts
function msToSeconds(milliseconds: number): number
```

**Parameters**

- `milliseconds`: Duration in milliseconds

**Returns** Duration in seconds

### `prefersReducedMotion`

Check if user prefers reduced motion

```ts
function prefersReducedMotion(): boolean
```

**Returns** Whether user prefers reduced motion

### `requestAnimFrame`

Request animation frame wrapper with fallback

```ts
function requestAnimFrame(callback: () => void): number
```

**Parameters**

- `callback`: Function to call on next frame

**Returns** Request ID

### `resolveAnimationConflict`

Resolve conflict between multiple animations
Returns the animation with the highest priority

```ts
function resolveAnimationConflict(
  animations: AnimationDescriptor[]
): AnimationDescriptor | null
```

### `resolveEdgeAnimationConflict`

Resolve conflict between multiple edge animations
Returns the animation that should be displayed

```ts
function resolveEdgeAnimationConflict(
  animations: AnimationDescriptor[]
): AnimationDescriptor | null
```

### `resolveNodeAnimationConflict`

Resolve conflict between multiple node animations
Returns the animation that should be displayed

```ts
function resolveNodeAnimationConflict(
  animations: AnimationDescriptor[]
): AnimationDescriptor | null
```

### `secondsToMs`

Convert animation duration from seconds to milliseconds

```ts
function secondsToMs(seconds: number): number
```

**Parameters**

- `seconds`: Duration in seconds

**Returns** Duration in milliseconds

### `shouldSimplifyAnimations`

Check if animation should be simplified for performance

```ts
function shouldSimplifyAnimations(
  animationCount: number,
  performanceThreshold: number = 50
): boolean
```

**Parameters**

- `animationCount`: Number of currently animating elements
- `performanceThreshold`: Threshold for simplification (default: 50)

**Returns** Whether to simplify animations

### `supportsAnimations`

Check if browser supports CSS animations

```ts
function supportsAnimations(): boolean
```

**Returns** Whether CSS animations are supported

### `throttle`

Throttle function for performance optimization
Useful for animation updates during continuous events

```ts
function throttle<T extends (...args: any[]) => any>(
  func: T,
  limit: number
): (...args: Parameters<T>) => void
```

**Parameters**

- `func`: Function to throttle
- `limit`: Time limit in milliseconds

**Returns** Throttled function

## Classes

### `AnimationPriorityResolver`

Animation priority resolver
Advanced resolver with configuration support

```ts
class AnimationPriorityResolver
```

**Methods**

- `constructor(config: Partial<PriorityResolverConfig> = {})`
- `resolve(animations: AnimationDescriptor[]): AnimationDescriptor[]` — Resolve animations based on configuration
- `updateConfig(config: Partial<PriorityResolverConfig>): void` — Update configuration
- `getConfig(): Readonly<PriorityResolverConfig>` — Get current configuration

## Constants

### `AnimationColorSchemes`

Common color schemes for animations

```ts
const AnimationColorSchemes: { readonly BLUE: readonly ["#3498db", "#2980b9"]; readonly GREEN: readonly ["#27ae60", "#229954"]; readonly RED: readonly ["#e74c3c", "#c0392b"]; readonly ORANGE: readonly ["#f39c12", "#e67e22"]; readonly PURPLE: readonly ["#9b59b6", "#8e44ad"]; readonly TEAL: readonly ["#1abc9c", "#16a085"]; readonly YELLOW: readonly ["#f1c40f", "#f39c12"]; readonly GRADIENT_COOL: readonly ["#667eea", "#764ba2"]; readonly GRADIENT_WARM: readonly ["#f093fb", "#f5576c"]; readonly GRADIENT_OCEAN: readonly ["#4facfe", "#00f2fe"]; readonly GRADIENT_SUNSET: readonly ["#fa709a", …
```

### `AnimationPresets`

Preset configurations for common workflow states

```ts
const AnimationPresets: { readonly WORKFLOW: { readonly RUNNING: { readonly node: { readonly status: "running"; readonly animateStatus: true; readonly style: { readonly animatedBorder: true; readonly borderAnimationType: "pulse"; readonly borderAnimationSpeed: 1.5; }; }; readonly link: LinkAnimation; }; readonly PROCESSING: { readonly node: { readonly status: "running"; readonly animateStatus: true; readonly style: { readonly animatedBorder: true; readonly borderAnimationType: "gradient"; readonly borderAnimationSpeed: 2; readonly borderAnimationColors: readonly ["#667eea", "#764ba2"]; }; }; …
```

### `AnimationSpeeds`

Common animation speed values

```ts
const AnimationSpeeds: { readonly VERY_SLOW: 0.5; readonly SLOW: 1; readonly NORMAL: 1.5; readonly FAST: 2; readonly VERY_FAST: 3; }
```

## Interfaces

### `AnimationDescriptor`

Animation descriptor for conflict resolution

```ts
interface AnimationDescriptor
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `type` | `AnimationType` |  |  |
| `priority?` | `number` |  |  |
| `borderType?` | `'gradient' \| 'pulse' \| 'breathe' \| 'shimmer'` |  |  |
| `status?` | `'idle' \| 'pending' \| 'running' \| 'completed' \| 'error' \| 'warning'` |  |  |
| `edgeType?` | `'marching-ants' \| 'flow' \| 'pulse' \| 'dash-flow'` |  |  |
| `customName?` | `string` |  |  |
| `metadata?` | `Record<string, any>` |  |  |

### `PriorityResolverConfig`

Priority resolver configuration

```ts
interface PriorityResolverConfig
```

**Properties**

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `allowCoexistence` | `boolean` |  | Allow multiple animations to coexist |
| `priorityOverrides?` | `Record<string, number>` |  | Custom priority overrides |
| `strictMode?` | `boolean` |  | Strict mode: throw error on conflicts instead of resolving |

## Types

### `AnimationType`

Also has every member of `String`, listed on its own entry.

Animation types for priority resolution

```ts
type AnimationType =
  | 'border'
  | 'status'
  | 'edge'
  | 'hover'
  | 'selected'
  | 'custom';
```

## Enums

### `AnimationPriority`

Animation priority levels (higher number = higher priority)

```ts
enum AnimationPriority
```

**Members**

- `BORDER_GRADIENT = 10`
- `BORDER_SHIMMER = 15`
- `BORDER_BREATHE = 20`
- `HOVER_STATE = 30`
- `SELECTED_STATE = 35`
- `BORDER_PULSE = 40`
- `EDGE_MARCHING_ANTS = 50`
- `EDGE_FLOW = 55`
- `EDGE_PULSE = 60`
- `EDGE_DASH_FLOW = 65`
- `STATUS_PENDING = 70`
- `STATUS_RUNNING = 75`
- `STATUS_WARNING = 80`
- `STATUS_COMPLETED = 85`
- `STATUS_ERROR = 90`
- `USER_INTERACTION = 95`
- `CUSTOM_ANIMATION = 100`
