# Classes

Import these from `@grafloria/engine`.

## Classes

### `ClipboardManager`

ClipboardManager handles copy/paste operations for diagram entities

Features:
- Serializes selected entities to clipboard format
- Handles relationship preservation (links between copied nodes)
- Supports cross-diagram paste (ID remapping)
- Maintains clipboard history

```ts
class ClipboardManager
```

**Methods**

- `copy(data: { nodes: NodeModel[]; links: LinkModel[]; groups: GroupModel[]; sourceDiagramId?: string; }): void` — Copy entities to clipboard
- `get(): ClipboardData | null` — Get clipboard data
- `claimPasteSlot(): number` — Claim the next paste slot for the CURRENT clipboard payload (1-based).

Repeat-pasting the same copy must cascade — the clipboard's serialized
positions are frozen at copy time, so a constant default offset lands
every paste on the exact same pixels and "paste" appears to work only
once (live report). Each PasteCommand claims its slot once (stable
across redo); a new copy() resets the cascade.
- `hasData(): boolean` — Check if clipboard has data
- `clear(): void` — Clear clipboard
- `getHistory(): ClipboardData[]` — Get clipboard history
- `isFromDiagram(diagramId: string): boolean` — Check if clipboard contains nodes from a specific diagram
- `getStats(): { nodeCount: number; linkCount: number; groupCount: number; timestamp: number | null; }` — Get clipboard statistics

### `EventBus`

```ts
class EventBus
```

**Methods**

- `constructor()`
- `emit(event: string, data?: any): void` — Emit an event
- `on(pattern: string, handler: Function): () => void` — Subscribe to events
- `once(pattern: string, handler: Function): void` — Subscribe once
- `off(pattern: string, handler: Function): void` — Unsubscribe from events
- `removeAllListeners(pattern?: string): void` — Remove all listeners
- `onFiltered( event: string, filter: (data: any) => boolean, handler: Function ): () => void` — Filtered subscription
- `onMapped<T, R>( event: string, mapper: (data: T) => R, handler: (data: R) => void ): () => void` — Mapped subscription
- `onDebounced( event: string, delay: number, handler: Function ): () => void` — Debounced subscription
- `onThrottled( event: string, delay: number, handler: Function ): () => void` — Throttled subscription
- `batch(fn: () => void): void` — Batch events
- `suspend(): void` — Suspend event emission
- `resume(): void` — Resume event emission
- `startRecording(): void` — Start recording events
- `stopRecording(): EventLogEntry[]` — Stop recording
- `getEventLog(): ReadonlyArray<EventLogEntry>` — Get event log
- `clearEventLog(): void` — Clear event log
- `replay(events: EventLogEntry[]): void` — Replay events
- `listenerCount(event: string): number` — Get listener count
- `eventNames(): string[]` — Get all event names

### `GridLayoutAlgorithm`

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

```ts
class GridLayoutAlgorithm extends BaseLayoutAlgorithm
```

**Methods**

- `constructor(config?: LayoutConfiguration)`
- `getName(): string` — Get the name of the layout algorithm
- `getType(): 'grid'` — Get the type of the layout algorithm
- `calculatePlacement(options: PlacementOptions): PlacementResult` — Calculate placement for a single new node
- `reLayout(diagram: DiagramModel, config?: LayoutConfiguration): Map<string, Point>` — Re-layout all nodes in grid pattern
- `override configure(config: LayoutConfiguration): void` — Configure grid-specific options
- `override canApply(diagram: DiagramModel): { valid: boolean; reason?: string }` — Grid layout can always be applied

### `HierarchicalLayoutAlgorithm`

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

```ts
class HierarchicalLayoutAlgorithm extends BaseLayoutAlgorithm
```

**Methods**

- `constructor(config?: LayoutConfiguration)`
- `getName(): string` — Get the name of the layout algorithm
- `getType(): 'hierarchical'` — Get the type of the layout algorithm
- `calculatePlacement(options: PlacementOptions): PlacementResult` — Calculate placement for a single new node
For hierarchical layout, we'll place it near connected nodes
- `reLayout(diagram: DiagramModel, config?: LayoutConfiguration): Map<string, Point>` — Re-layout all nodes using Dagre
- `override configure(config: LayoutConfiguration): void` — Configure hierarchical-specific options
- `override canApply(diagram: DiagramModel): { valid: boolean; reason?: string }` — Hierarchical layout works best on DAGs but can handle any graph

### `HtmlTemplateRenderer`

HTML Template Renderer
Framework-agnostic HTML template rendering with EventBus integration

Features:
- LemonadeJS template rendering
- Data binding from NodeModel.data
- Event handlers connected to EventBus
- Component mode support (pass-through for framework-specific rendering)
- Proper resource cleanup to prevent memory leaks

```ts
class HtmlTemplateRenderer
```

**Methods**

- `constructor(private eventBus: EventBus)`
- `render(config: HtmlConfig, node: NodeModel): RenderResult` — Render HTML configuration to result
- `disposeNode(nodeUuid: string): void` — Dispose resources for a specific node
- `dispose(): void` — Cleanup all renderer resources

### `LemonadeJSRenderer`

LemonadeJS Enhanced Renderer
Full LemonadeJS runtime with two-way binding

Features:
- Real LemonadeJS template rendering
- Two-way data binding (:bind)
- Reactive updates (automatic re-rendering on data changes)
- Event handlers (:click, :change, etc.)
- EventBus integration (all events flow through engine)
- Component mode support

```ts
class LemonadeJSRenderer
```

**Methods**

- `constructor(private eventBus: EventBus)`
- `render(config: HtmlConfig, node: NodeModel): LemonadeRenderResult` — Render HTML configuration to LemonadeJS element
- `disposeNode(nodeUuid: string): void` — Dispose resources for a specific node
- `dispose(): void` — Cleanup all renderer resources

### `MobilePerformanceService`

```ts
class MobilePerformanceService
```

**Methods**

- `static isMobileDevice(): boolean` (static) — Detect if running on mobile device
- `static isLowPowerDevice(): boolean` (static) — Detect if low-power device
- `initialize(customConfig?: Partial<MobilePerformanceConfig>)` — Initialize with auto-detection
- `throttle<T extends (...args: any[]) => any>( key: string, fn: T, wait: number = this.config.touchMoveThrottle ): (...args: Parameters<T>) => void` — Throttle function execution
- `getRenderQuality(): 'high' | 'medium' | 'low'` — Get recommended render quality based on device
- `shouldSkipRender(nodeCount: number): boolean` — Should skip rendering based on performance config
- `getConfig(): MobilePerformanceConfig` — Get configuration
- `updateConfig(config: Partial<MobilePerformanceConfig>)` — Update configuration

### `PerformanceMonitor`

```ts
class PerformanceMonitor
```

**Methods**

- `constructor(config: PerformanceConfig = {})`
- `measure<T>(name: string, fn: () => T | Promise<T>): T | Promise<T>` — Measure operation performance
- `setWarnThreshold(threshold: number): void` — Set warning threshold
- `getReport(): PerformanceReport` — Get performance report
- `clear(): void` — Clear all metrics

### `PluginManager`

```ts
class PluginManager
```

**Methods**

- `constructor( engine: any, eventBus: any, config: PluginManagerConfig = {} )`
- `register(plugin: Plugin, config: Record<string, any> = {}): void` — Register a plugin (without installing)
- `async install(pluginName: string): Promise<void>` — Install a plugin
- `async uninstall(pluginName: string): Promise<void>` — Uninstall a plugin
- `async activate(pluginName: string): Promise<void>` — Activate a plugin
- `async deactivate(pluginName: string): Promise<void>` — Deactivate a plugin
- `get(pluginName: string): Plugin | undefined` — Get plugin by name
- `has(pluginName: string): boolean` — Check if plugin is registered
- `isInstalled(pluginName: string): boolean` — Check if plugin is installed
- `isActive(pluginName: string): boolean` — Check if plugin is active
- `getState(pluginName: string): PluginState | undefined` — Get plugin state
- `list(): PluginMetadata[]` — List all registered plugins
- `listInstalled(): PluginMetadata[]` — List installed plugins
- `listActive(): PluginMetadata[]` — List active plugins
- `async unregister(pluginName: string): Promise<void>` — Unregister a plugin (removes from registry)
- `async installAll(): Promise<void>` — Install all registered plugins
- `async uninstallAll(): Promise<void>` — Uninstall all plugins
- `async clear(): Promise<void>` — Clear all plugins (uninstall and unregister)
