# IO-Reactive

A lightweight and fast next-generation reactive UI library for the web. Supports directives, islands architecture, high performance, and minimal bundle size.

---

## Advantages

-   **Minimal size**: <100kB (gzip)
-   **High performance**: optimized rendering and updates
-   **Directives**: declarative binding, validation, masks, custom behaviors
-   **Islands architecture**: partial hydration, SSR, lazy component loading
-   **Compatibility**: easily integrates into existing projects
-   **TypeScript-first**: strict typing, JSDoc

---

## Installation

```bash
npm install io-reactive
```

---

## Quick Start

### Minimal Example

```typescript
import { IO, tag } from 'io-reactive';

// Create a simple component
function MyApp() {
    return new IO(tag.DIV, {
        text: 'Hello, world!',
        classList: ['app-container'],
    });
}

// Initialize the app
const root = document.getElementById('app');
if (root) {
    const app = MyApp();
    root.appendChild(app.render());
}
```

### Interactive Example with State

```typescript
import { IO, tag } from 'io-reactive';

function CounterApp() {
    const io = new IO(tag.DIV);

    // Use built-in state
    const [count, setCount] = io.state<number>(0);

    io.components = [
        () =>
            new IO(tag.H1, {
                text: () => `Counter: ${count()}`,
            }),
        () =>
            new IO(tag.BUTTON, {
                text: 'Increment',
                events: {
                    click: () => setCount(count() + 1),
                },
            }),
    ];

    return io;
}

// Run the app
document.addEventListener('DOMContentLoaded', () => {
    const root = document.getElementById('app');
    if (root) {
        root.appendChild(CounterApp().render());
    }
});
```

---

## Core Features

### 1. Islands Architecture

Revolutionary technology for web optimization. Static content is rendered on the server without JavaScript, and interactive "islands" are hydrated as needed.

#### Static Components

```typescript
// Static component (SSR, no JS on client)
const header = IO.static('header', {
    classList: ['site-header'],
    text: 'My Site',
});

const page = IO.static('main', {}, [() => header, () => IO.static('p', { text: 'Static content for SEO' })]);
```

#### Interactive Islands

```typescript
// Interactive island with hydration
const counterIsland = IO.island('div', {
    hydration: { 'client:visible': true }, // Lazy hydration
    fallback: () => IO.static('div', { text: 'Loading...' }),
    component: () => {
        const counter = new IO('div');
        const [count, setCount] = counter.state(0);

        counter.components = [
            () => new IO('span', { text: `Count: ${count()}` }),
            () =>
                new IO('button', {
                    text: '+',
                    events: { click: () => setCount(count() + 1) },
                }),
        ];

        return counter;
    },
});

// Hybrid page
const hybridPage = IO.static('main', {}, [
    () => IO.static('h1', { text: 'Static page' }),
    () => counterIsland(), // Interactive island
    () => IO.static('footer', { text: 'Static footer' }),
]);
```

#### Hydration Strategies

-   **`client:load`** — immediate hydration
-   **`client:idle`** — hydration when browser is idle
-   **`client:visible`** — lazy hydration (on viewport)
-   **`client:media`** — conditional hydration (media queries)

#### Data Bridge System

```typescript
import { IslandDataBridge } from 'io-reactive';

// Set data between islands
IslandDataBridge.setData('user', { name: 'John', theme: 'dark' });

// Subscribe to changes
IslandDataBridge.subscribe('user', (userData) => {
    updateTheme(userData.theme);
});
```

**📖 [Detailed documentation on islands architecture](./docs/islands-architecture.md)**

### 2. Directives

-   **model** — two-way binding:
    ```ts
    <input :model="[() => state.value, v => state.value = v]" />
    ```
-   **validate** — validation:
    ```ts
    <input :model="..." :validate="v => v.length > 2 || 'At least 3 characters'" />
    ```
-   **onSubmit** — handle Enter:
    ```ts
    <input :model="..." :onSubmit="v => alert(v)" />
    ```
-   **debounce** — update delay:
    ```ts
    <input :model="..." :debounce="300" />
    ```
-   **custom** — your own directives:
    ```ts
    <input :custom="[{ name: 'my', init: (el, v) => ... }]" />
    ```

### 3. Reactivity

-   **Signals and state**:
    ```ts
    const count = IO.signal(0);
    count.value++;
    ```
-   **Automatic effects**:
    ```ts
    IO.effect(() => console.log(count.value));
    ```

### 4. Validation and Forms

-   **Built-in validators**:
    ```ts
    import { required, minLength } from 'io-reactive/validators';
    <input :validate="required" />
    <input :validate="minLength(3)" />
    ```
-   **Input masks**:
    ```ts
    <input :mask="{ pattern: '+1 (###) ###-####' }" />
    ```

### 5. Integration and Extensibility

-   **Compatible with any framework** (can be used as standalone directives or islands)
-   **Extensible architecture**: write your own directives, plugins, islands

---

## Performance

### Islands architecture provides:

-   **Minimal JavaScript bundle** — only code for interactive islands is loaded
-   **Fast Time-to-Interactive** — critical content is static
-   **Core Web Vitals optimization** — lazy hydration does not block rendering
-   **SEO benefits** — static HTML is fully indexed

---

## Documentation and Examples

-   **[Islands architecture](./docs/islands-architecture.md)** — detailed guide on Islands
-   [Documentation and guides](./src/IO/docs/)
-   [Demos and examples](../demo-site/)
-   [Plans and architecture](./plans/)

---

## License

MIT

## Публикация пакета и типы

### Как опубликовать новую версию

1. Увеличьте версию:
   ```bash
   npm version patch --no-git-tag-version --workspace=packages/io-reactive
   ```
2. Соберите пакет:
   ```bash
   npm run build -w io-reactive
   ```
3. Проверьте, что в dist/ есть .js и .d.ts:
   ```bash
   ls packages/io-reactive/dist/
   ```
4. Опубликуйте:
   ```bash
   npm publish --access public --workspace=packages/io-reactive
   ```

### Как работают типы
- Все типы автоматически подтягиваются через зависимость @oi-reactive/shared-types.
- Пользователю не нужно явно устанавливать shared-types — типы доступны "из коробки" после установки io-reactive.
