# @nebula/core-utils

Small, dependency-free utilities shared across Nebula Core packages. No DOM or platform assumptions.

## Why it exists
Controller-first apps often duplicate tiny helpers (math, events, clamping). This package centralizes those primitives without imposing any UI or input model.

## Installation

```bash
npm install @nebula/core-utils
```

## Usage

```js
import { clamp, createEmitter, lerp, roundTo } from "@nebula/core-utils";

const value = clamp(12, 0, 10); // 10
const blended = lerp(0, 100, 0.25); // 25
const rounded = roundTo(3.14159, 2); // 3.14

const inputEvents = createEmitter();
const unsubscribe = inputEvents.on((payload) => {
  console.log("input", payload);
});

inputEvents.emit({ action: "confirm" });
unsubscribe();
```

## API

### clamp(value, min, max)

Clamp a number between a minimum and maximum.

**Parameters**
- `value` (`number`): The value to clamp.
- `min` (`number`): Lower bound.
- `max` (`number`): Upper bound.

**Returns**
- `number`: The clamped value.

**Examples**
```js
clamp(5, 0, 10); // 5
clamp(-2, 0, 10); // 0
clamp(99, 0, 10); // 10
```

### lerp(from, to, t)

Linear interpolation between two numbers.

**Parameters**
- `from` (`number`): Start value.
- `to` (`number`): End value.
- `t` (`number`): Interpolation factor in the range 0..1.

**Returns**
- `number`: Interpolated value.

**Examples**
```js
lerp(0, 10, 0); // 0
lerp(0, 10, 1); // 10
lerp(0, 10, 0.5); // 5
```

### roundTo(value, decimals)

Round a number to a specific decimal precision.

**Parameters**
- `value` (`number`): The value to round.
- `decimals` (`number`): Number of decimal places.

**Returns**
- `number`: Rounded value.

**Examples**
```js
roundTo(1.005, 2); // 1.01
roundTo(123.4567, 1); // 123.5
```

### createEmitter()

Create a tiny event emitter for a single payload type. The emitter provides three methods: `on`, `emit`, and `clear`.

**Returns**
An object with the shape:

```ts
{
  on: (listener: (payload: T) => void) => () => void;
  emit: (payload: T) => void;
  clear: () => void;
}
```

**Methods**
- `on(listener)`: Registers a listener. Returns an `unsubscribe()` function.
- `emit(payload)`: Calls all listeners with the payload.
- `clear()`: Removes all listeners.

**Examples**
```js
const events = createEmitter();
const off = events.on((payload) => {
  console.log(payload);
});

events.emit({ type: "focus", id: "button-1" });
off();
events.clear();
```

## TypeScript / IntelliSense
This package ships as ES Modules with JSDoc annotations, so you get editor IntelliSense out of the box in TypeScript-aware editors.

## SteamOS / Steam Deck notes
This package is platform-agnostic and safe to use in any runtime (browser, Electron, Node).

## License
MIT
