# chainEvent

Combines a user handler with component-required behavior for one native event.

## Signatures

```ts
export declare function chainEvent<Ev extends Event, E1 = never, R1 = never, E2 = never, R2 = never>(user: EventHandlerInput<Ev, E1, R1>, internal: EventHandlerInput<Ev, E2, R2>): EventHandler.EventHandler<Ev, E1 | E2, R1 | R2> | undefined;
```

## Why

Component hosts must combine user and required behavior without hiding the
precise Effect boundary. User callback invocation constructs the user Effect
first. Internal callback invocation may then construct an internal Effect;
only execution of that returned Effect is sequenced after the user Effect.

## Ownership and lifetime

The returned `EventHandler` owns no listener by itself. The rendering Scope
installs it and removes it; `once` and AbortSignal state are honored for each
input independently. Capture and passive options are conservatively merged.

## DOM behavior

The user handler receives a retained `Proxy` around the browser event so a
`preventDefault()` call made while its Effect runs can still cancel the
internal step. The proxy is not identity-equal to the native event. Its
properties—including `currentTarget`—are read from that native event, so
`currentTarget` becomes null after browser dispatch exactly as it normally
does. The internal handler receives the original native event, never the
proxy.

## Invocation and Effect sequencing

`userHandler.handler(proxy)` is called first to construct `userEffect`. If
that invocation has already called `preventDefault()`—for example through an
EventHandler option—the internal handler is not invoked. Otherwise,
`internalHandler.handler(nativeEvent)` is called immediately to construct
`internalEffect`, before `userEffect` runs. A void-returning internal callback
therefore performs its callback body eagerly and cannot be undone by a later
`preventDefault()` inside `userEffect`. The composed Effect runs `userEffect`,
checks tracked default prevention again, and only then runs a returned
`internalEffect` when it is still allowed.

## Examples

```ts
import { chainEvent } from "@typed/ui/Dom/Events"
import { EventHandler } from "@typed/template"
import { Effect } from "effect"

const calls: Array<string> = []
const handler = chainEvent(
  EventHandler.make((event: MouseEvent) =>
    Effect.sync(() => {
      calls.push("user effect")
      event.preventDefault()
    })),
  EventHandler.make(() => {
    calls.push("internal callback") // runs while constructing the Effect
    return Effect.sync(() => calls.push("internal effect"))
  })
)!

const program = handler.handler(new MouseEvent("click", { cancelable: true }))
// calls is now ["internal callback"]
await Effect.runPromise(program)
// calls is ["internal callback", "user effect"];
// the returned internal Effect was gated by preventDefault.
```
