npm package: @flightdev/ui-react
Description: React 18+ SSR adapter for Flight Framework - streaming, hydration, islands
Latest version: 1.1.0

# @flightdev/ui-react

React 18+ SSR adapter for Flight Framework. Provides server-side rendering with streaming, hydration, and islands architecture support.

## Table of Contents

- [Installation](#installation)
- [Quick Start](#quick-start)
- [SSR Options](#ssr-options)
- [Streaming SSR](#streaming-ssr)
- [Islands Architecture](#islands-architecture)
- [React Server Components](#react-server-components)
- [Hydration](#hydration)
- [API Reference](#api-reference)
- [License](#license)

---

## Installation

```bash
npm install @flightdev/ui @flightdev/ui-react
```

Peer dependencies:

```bash
npm install react react-dom
```

---

## Quick Start

```typescript
import { defineUI } from '@flightdev/ui';
import { react } from '@flightdev/ui-react';

const ui = defineUI(react());

const result = await ui.adapter.renderToString({
    component: App,
    props: { user: { name: 'John' } },
});

console.log(result.html);
```

---

## SSR Options

Configure the React adapter with options:

```typescript
import { react } from '@flightdev/ui-react';

const adapter = react({
    streaming: true,
    serverComponents: false,
    onError: (error) => {
        console.error('[SSR Error]', error.message);
    },
    onShellReady: () => {
        console.log('Shell rendered');
    },
});
```

### Available Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `streaming` | `boolean` | `false` | Enable streaming SSR |
| `serverComponents` | `boolean` | `false` | Enable React Server Components |
| `onError` | `function` | - | Error callback for SSR errors |
| `onShellReady` | `function` | - | Callback when shell is ready |

---

## Streaming SSR

React 18 supports streaming SSR with Suspense boundaries:

```typescript
import { react } from '@flightdev/ui-react';

const adapter = react();

function App({ user }) {
    return (
        <main>
            <h1>Welcome, {user.name}</h1>
            <Suspense fallback={<Spinner />}>
                <UserDashboard userId={user.id} />
            </Suspense>
        </main>
    );
}

const { stream, done, abort } = adapter.renderToStream(
    { component: App, props: { user } },
    { url: request.url },
    {
        timeout: 10000,
        onShellReady: () => {
            response.writeHead(200, {
                'Content-Type': 'text/html',
                'Transfer-Encoding': 'chunked',
            });
        },
        onError: (error) => {
            console.error('[Stream Error]', error);
        },
    }
);

const reader = stream.getReader();
while (true) {
    const { done: readerDone, value } = await reader.read();
    if (readerDone) break;
    response.write(value);
}
response.end();
```

---

## Islands Architecture

Create interactive islands within static content:

```typescript
const adapter = react();

const profileIsland = adapter.createIsland(
    'UserProfile',
    { userId: '123' },
    {
        hydrate: 'visible',  // Hydrate when visible in viewport
        priority: 10,
    }
);

const html = `
<div class="page">
    <header>Static content</header>
    ${profileIsland.placeholder}
    <footer>Static content</footer>
</div>
`;
```

### Hydration Strategies

| Strategy | Description |
|----------|-------------|
| `idle` | Hydrate when browser is idle |
| `visible` | Hydrate when element is visible |
| `interaction` | Hydrate on first user interaction |
| `media` | Hydrate based on media query |

---

## React Server Components

Enable React Server Components for zero-bundle server rendering:

```typescript
const adapter = react({
    serverComponents: true,
});

// Server Component (no client JS)
async function UserList() {
    const users = await db.users.findMany();
    return (
        <ul>
            {users.map(user => (
                <li key={user.id}>{user.name}</li>
            ))}
        </ul>
    );
}
```

---

## Hydration

Generate hydration scripts for client-side interactivity:

```typescript
const result = await adapter.renderToString({
    component: App,
    props: { data },
});

const hydrationScript = adapter.getHydrationScript(result);

const html = `
<!DOCTYPE html>
<html>
<body>
    <div id="app">${result.html}</div>
    ${hydrationScript}
</body>
</html>
`;
```

### Progressive Hydration

React 18 supports progressive hydration with `hydrateRoot`:

```typescript
// Client entry
import { hydrateRoot } from 'react-dom/client';

const container = document.getElementById('app');
const root = hydrateRoot(container, <App {...window.__FLIGHT_DATA__.props} />);
```

---

## API Reference

### react(options?)

Create a React adapter instance.

```typescript
function react(options?: ReactAdapterOptions): ReactAdapter;
```

### ReactAdapter

| Method | Description |
|--------|-------------|
| `renderToString(component, context?)` | Render to HTML string |
| `renderToStream(component, context?, options?)` | Render to readable stream |
| `getHydrationScript(result)` | Generate hydration script |
| `getClientEntry()` | Get client entry code |
| `createIsland(name, props, options?)` | Create an island |

### Capabilities

| Capability | Supported |
|------------|-----------|
| Streaming | Yes |
| Partial Hydration | Yes |
| Islands | Yes |
| Resumable | No |
| SSG | Yes |
| CSR | Yes |
| Server Components | Yes |

---

## License

MIT