# Derived

Combine independent keyed claims through an explicit resolution policy.



<DemoPreview name="Derived" />

## Usage [#usage]

```ts
import { Derived, latestOf, maxOf } from '@joycostudio/xyz'

const blur = new Derived(0, maxOf)
blur.set('scroll', 0.4)
blur.set('modal', 0.9)
blur.value // 0.9
blur.clear('modal')
blur.value // 0.4

const focus = new Derived('scene', latestOf<string>)
focus.set('modal', 'settings')
focus.value // 'settings'
focus.clear('modal')
focus.value // 'scene'
```

## API [#api]

### new Derived [#new-derived]

```ts
new Derived<In, Out = In>(fallback: Out, combine: (slots: In[], fallback: Out) => Out)
```

Creates a keyed value with an explicit fallback and resolution policy.

| Argument   | Description                                                                                                                                                              |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `fallback` | Value passed to the resolver as its default. The resolver decides how it participates in the result.                                                                     |
| `combine`  | Receives current slot values in insertion order and the fallback whenever `.value` is read. Returns the resolved value, which may have a different type from the inputs. |

```ts
const blur = new Derived(0, maxOf)
blur.value // 0
```

### set [#set]

```ts
derived.set(key: string, value: In): void
```

Creates or replaces one owner's claim. Updating an existing key preserves its insertion position.

| Argument | Description                                |
| -------- | ------------------------------------------ |
| `key`    | Identifier for the owner making the claim. |
| `value`  | The owner's input to the resolver.         |

```ts
const blur = new Derived(0, maxOf)
blur.set('scroll', 0.4)
blur.set('scroll', 0.8)
blur.value // 0.8
```

### clear [#clear]

```ts
derived.clear(key: string): void
```

Removes one owner's claim. Missing keys are ignored.

| Argument | Description                        |
| -------- | ---------------------------------- |
| `key`    | Identifier of the claim to remove. |

```ts
const blur = new Derived(0, maxOf)
blur.set('scroll', 0.4)
blur.set('modal', 0.9)
blur.clear('modal')
blur.value // 0.4
```

### value [#value]

```ts
derived.value // Out
```

Read-only resolved value. Each read calls `combine` with the current claims without mutating them.

### size [#size]

```ts
derived.size // number
```

Read-only count of active claims.

### maxOf [#maxof]

```ts
maxOf(values: number[], fallback: number): number
```

Returns the highest active value, never below the fallback. Pass it as `Derived`'s `combine` argument for numeric maximum resolution.

| Argument   | Description                                             |
| ---------- | ------------------------------------------------------- |
| `values`   | Current numeric claims.                                 |
| `fallback` | Minimum result, also returned when there are no claims. |

```ts
maxOf([0.4, 0.9], 0) // 0.9
maxOf([], 0.2) // 0.2
```

### latestOf [#latestof]

```ts
latestOf<T>(values: T[], fallback: T): T
```

Returns the last value in the array. With `Derived`, this selects the most recently inserted active claim; updating an existing key does not move it to the end.

| Argument   | Description                              |
| ---------- | ---------------------------------------- |
| `values`   | Current claims in insertion order.       |
| `fallback` | Value returned when there are no claims. |

```ts
latestOf(['scene', 'modal'], 'scene') // 'modal'
latestOf([], 'scene') // 'scene'
```
