# RenderEvent

Represents the result of a rendering operation.
Can be either a DOM-based event (containing actual Nodes) or an HTML-based event (containing strings).

## Signatures

```ts
export type RenderEvent = DomRenderEvent | HtmlRenderEvent;
```

## Why

`RenderEvent` is the small output boundary shared by Typed renderers. Once a
producer exposes `Fx<RenderEvent, E, R>`, DOM templates, streamed SSR, routers,
and external renderers compose without a virtual component-tree protocol.
The Fx still carries every failure and required Effect service.

## Ownership and lifetime

A RenderEvent transports output; it does not acquire or retain the producer.
The producing Fx and its running Effect `Scope` own subscriptions,
interruption, ordering, and finalization. A consumer owns only the DOM range
or HTML stream position to which it applies the event.

## Representation

`DomRenderEvent` preserves existing DOM identity. `HtmlRenderEvent` carries
trusted renderer-owned HTML chunks for server output. Consumers can branch on
the public discriminant without hidden renderer state. DOM handler events are
a separate concern and use EventSource's documented forwarding `Proxy`.

## Examples

```ts
import { html } from "@typed/template"
import {
  isDomRenderEvent,
  isHtmlRenderEvent
} from "@typed/template/RenderEvent"
import { Fx } from "@typed/fx"
import { Option } from "effect"

const template = html`<div>Hello</div>`;

// Render events are emitted by the template Fx
const program = Fx.gen(function* () {
  const maybeEvent = yield* Fx.first(template);

  return Option.match(maybeEvent, {
    onNone: () => Fx.empty,
    onSome: (event) => {
      if (isDomRenderEvent(event)) {
        const nodes = event.valueOf();
        console.log(nodes);
      } else if (isHtmlRenderEvent(event)) {
        const html = event.toString();
        console.log(html);
      }

      // Fx.gen setup must return the Fx that runs afterward.
      return Fx.succeed(event);
    },
  });
});
```
