# Disposer

Collect owner-local cleanup work and unwind it safely in reverse order.



<DemoPreview name="Disposer" />

## Usage [#usage]

```ts
import { Disposer } from '@joycostudio/xyz'

const cleanup = new Disposer()
cleanup.listen(window, 'resize', () => console.log(window.innerWidth))

const timer = setInterval(() => console.log('tick'), 1000)
cleanup.add(() => clearInterval(timer))

// When the owner is removed: stop the timer, then remove the listener.
cleanup.dispose()
```

## API [#api]

### new Disposer [#new-disposer]

```ts
new Disposer()
```

Creates an owner-local cleanup stack. Takes no arguments.

### add [#add]

```ts
cleanup.add<T extends TeardownInput>(teardown: T): T
```

Registers cleanup and returns the original argument unchanged. Cleanups added after disposal run immediately.

| Argument   | Description                                                                                                                             |
| ---------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `teardown` | A cleanup function, an object with `dispose()`, or a readonly array of either. Arrays register left to right and dispose right to left. |

```ts
const cleanup = new Disposer()
const timer = setInterval(() => console.log('tick'), 1000)
cleanup.add(() => clearInterval(timer))
```

### listen [#listen]

```ts
cleanup.listen<T extends Event>(
  target: EventTarget,
  type: string,
  listener: (event: T) => void,
  options?: AddEventListenerOptions | boolean
): void
```

Adds an event listener and registers its removal with the same options.

| Argument   | Description                                                                                                           |
| ---------- | --------------------------------------------------------------------------------------------------------------------- |
| `target`   | The `EventTarget` to listen on, such as `window` or an element.                                                       |
| `type`     | Event name, such as `'resize'`.                                                                                       |
| `listener` | Callback receiving the event. Supply a type argument such as `KeyboardEvent` when you need event-specific properties. |
| `options?` | Standard `addEventListener` options or a boolean capture flag. Passed through unchanged.                              |

```ts
const cleanup = new Disposer()
cleanup.listen<KeyboardEvent>(
  window,
  'keydown',
  (event) => {
    console.log(event.code)
  },
  { capture: true }
)
```

### disposed [#disposed]

```ts
cleanup.disposed // boolean
```

Read-only flag indicating whether disposal has begun.

### dispose [#dispose]

```ts
cleanup.dispose(): void
```

Runs all cleanups once in reverse registration order. Takes no arguments; subsequent calls do nothing. Cleanup continues after failures: one failure is rethrown, while multiple failures become an `AggregateError`.
