npm package: @servlyadmin/runtime-svelte
Description: Svelte wrapper for Servly runtime renderer
Author: Servly
Latest version: 0.1.52

# @servlyadmin/runtime-svelte

Svelte wrapper for Servly runtime renderer. Render Servly components in your Svelte 5 applications with full slot support, state management, and reactive updates.

## Installation

```bash
npm install @servlyadmin/runtime-svelte
# or
yarn add @servlyadmin/runtime-svelte
# or
pnpm add @servlyadmin/runtime-svelte
```

## Requirements

- Svelte 5.0.0 or higher
- @servlyadmin/runtime-core (installed automatically)

## Quick Start

```svelte
<script lang="ts">
  import { ServlyComponent } from '@servlyadmin/runtime-svelte';
</script>

<!-- That's it! Components are fetched from Servly's registry automatically -->
<ServlyComponent
  id="my-component-id"
  props={{ title: 'Hello World' }}
/>
```

## Registry & Caching

### Default Registry

Components are fetched from Servly's production registry by default:
- **URL**: `https://core-api.servly.app/v1/views/registry`

To use a custom registry:

```typescript
import { setRegistryUrl } from '@servlyadmin/runtime-svelte';

setRegistryUrl('https://your-api.com/v1/views/registry');
```

### Cache Strategies

The runtime supports three caching strategies:

| Strategy | Description | Persistence | Best For |
|----------|-------------|-------------|----------|
| `localStorage` | Persists across browser sessions | Yes | **Production (default)** |
| `memory` | In-memory cache, cleared on refresh | No | Development, SSR |
| `none` | No caching, always fetches fresh | No | Testing, debugging |

```svelte
<!-- Default: localStorage caching -->
<ServlyComponent id="my-component" />

<!-- Explicit cache strategy -->
<ServlyComponent id="my-component" cacheStrategy="memory" />

<!-- No caching -->
<ServlyComponent id="my-component" cacheStrategy="none" />
```

## API Reference

### Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `id` | `string` | **required** | Component ID from the registry |
| `version` | `string` | `'latest'` | Version specifier |
| `props` | `object` | `{}` | Props to pass to the component |
| `cacheStrategy` | `'localStorage' \| 'memory' \| 'none'` | `'localStorage'` | Caching strategy |
| `retryConfig` | `object` | `undefined` | Retry configuration |
| `eventHandlers` | `object` | `undefined` | Event handlers keyed by element ID |
| `showSkeleton` | `boolean` | `true` | Show loading skeleton |
| `enableStateManager` | `boolean` | `false` | Enable state management |
| `initialState` | `object` | `undefined` | Initial state |
| `slotContent` | `Record<string, HTMLElement>` | `{}` | Programmatic slot content |

### Callbacks

| Callback | Type | Description |
|----------|------|-------------|
| `onload` | `(data: ComponentData) => void` | Called on successful load |
| `onerror` | `(error: Error) => void` | Called on load failure |
| `onready` | `() => void` | Called when fully rendered |
| `onstatechange` | `(event: StateChangeEvent) => void` | Called on state change |

```svelte
<script lang="ts">
  import { ServlyComponent } from '@servlyadmin/runtime-svelte';

  function handleLoad(data) {
    console.log('Component loaded:', data);
  }

  function handleError(error) {
    console.error('Failed to load:', error);
  }
</script>

<ServlyComponent
  id="my-component"
  onload={handleLoad}
  onerror={handleError}
/>
```

## Advanced Usage

### With State Management

```svelte
<script lang="ts">
  import { ServlyComponent } from '@servlyadmin/runtime-svelte';

  let count = $state(0);

  function handleStateChange(event) {
    if (event.path === 'count') {
      count = event.value;
    }
  }
</script>

<ServlyComponent
  id="counter-component"
  props={{ count }}
  enableStateManager={true}
  initialState={{ count: 0 }}
  onstatechange={handleStateChange}
/>

<p>Count: {count}</p>
```

### With Event Handlers

```svelte
<script lang="ts">
  import { ServlyComponent } from '@servlyadmin/runtime-svelte';

  const handlers = {
    'submit-btn': {
      click: (event) => {
        console.log('Submit clicked!');
      },
    },
    'email-input': {
      change: (event) => {
        console.log('Email:', event.target.value);
      },
    },
  };
</script>

<ServlyComponent
  id="form-component"
  eventHandlers={handlers}
/>
```

### Accessing Component Methods

```svelte
<script lang="ts">
  import { ServlyComponent } from '@servlyadmin/runtime-svelte';

  let servlyComponent;

  function reload() {
    servlyComponent.reload();
  }

  function updateProps() {
    servlyComponent.update({ newProp: 'value' });
  }
</script>

<ServlyComponent
  bind:this={servlyComponent}
  id="my-component"
/>

<button onclick={reload}>Reload</button>
<button onclick={updateProps}>Update Props</button>
```

### Reactive Props

```svelte
<script lang="ts">
  import { ServlyComponent } from '@servlyadmin/runtime-svelte';

  let count = $state(0);
  let title = $state('Hello');
</script>

<ServlyComponent
  id="my-component"
  props={{ count, title }}
/>

<button onclick={() => count++}>Increment</button>
<input bind:value={title} />
```

### Version Specifiers

```svelte
<!-- Exact version -->
<ServlyComponent id="my-component" version="1.2.3" />

<!-- Caret range (compatible with) -->
<ServlyComponent id="my-component" version="^1.0.0" />

<!-- Tilde range (approximately) -->
<ServlyComponent id="my-component" version="~1.2.0" />

<!-- Latest version (default) -->
<ServlyComponent id="my-component" />
```

## Exported Methods

The ServlyComponent exposes these methods via `bind:this`:

| Method | Description |
|--------|-------------|
| `reload()` | Reload the component from registry |
| `update(props)` | Update component with new props |
| `getSlotElement(name)` | Get a slot element by name |
| `getSlotNames()` | Get all available slot names |
| `mountIntoSlot(name, element)` | Mount an element into a slot |
| `getStateManager()` | Get the state manager instance |

## Re-exported Utilities

```typescript
import {
  // Fetching
  fetchComponent,
  prefetchComponents,
  setRegistryUrl,
  DEFAULT_REGISTRY_URL,
  
  // Caching
  invalidateCache,
  clearAllCaches,
  
  // State management
  StateManager,
  
  // Event system
  EventSystem,
  getEventSystem,
} from '@servlyadmin/runtime-svelte';
```

## Styling

The component includes default styles for loading and error states:

```css
/* Override default styles */
:global(.servly-skeleton) {
  background-color: #e5e7eb;
  animation: pulse 2s infinite;
}

:global(.servly-error) {
  background-color: #fee2e2;
  color: #dc2626;
}
```

## License

MIT