Cleanup: Remove old modes, add Svelte 5 reference library, update orchestrator

- Delete Mode1Test, Mode2Test, Mode3Test, Mode5Test (keep only Mode6Test)
- Delete old documentation, Docker files, and k8s configs
- Add comprehensive Svelte 5 reference library (svelte-reference/)
- Update ModeSwitch orchestrator:
  - Fix port to 3005 (never use 3000/3001)
  - Add API endpoints for mode switching
  - Add bun-types and proper tsconfig
  - Clean up mode folder mappings
This commit is contained in:
2026-01-21 03:56:01 +00:00
parent 42ff3e8f33
commit 0b76a4b119
223 changed files with 8861 additions and 362834 deletions
+439
View File
@@ -0,0 +1,439 @@
# Svelte 5 Runes Complete Guide
## Overview
Runes are Svelte 5's new reactivity system. They replace the old `$:` reactive statements and `export let` declarations with explicit, predictable primitives.
---
## 📦 `$state` - Reactive State
### Basic Usage
```svelte
<script lang="ts">
let count = $state(0);
let user = $state({ name: 'John', age: 30 });
let items = $state<string[]>([]);
</script>
<button onclick={() => count++}>
Clicked {count} times
</button>
```
### Deep Reactivity
```svelte
<script lang="ts">
// Objects and arrays are deeply reactive
let todos = $state([
{ id: 1, text: 'Learn Svelte', done: false }
]);
function toggle(id: number) {
const todo = todos.find(t => t.id === id);
if (todo) todo.done = !todo.done; // This triggers updates!
}
</script>
```
### `$state.raw` - Shallow Reactivity
```svelte
<script lang="ts">
// Use for large objects where you replace, not mutate
let data = $state.raw<BigObject | null>(null);
async function load() {
data = await fetchData(); // Must reassign, not mutate
}
</script>
```
### `$state.snapshot` - Get Plain Object
```svelte
<script lang="ts">
let user = $state({ name: 'John' });
function save() {
// Get a plain, non-reactive copy
const plain = $state.snapshot(user);
localStorage.setItem('user', JSON.stringify(plain));
}
</script>
```
---
## 🔗 `$derived` - Computed Values
### Basic Derived
```svelte
<script lang="ts">
let count = $state(0);
let doubled = $derived(count * 2);
let quadrupled = $derived(doubled * 2);
</script>
<p>{count} × 2 = {doubled}</p>
<p>{doubled} × 2 = {quadrupled}</p>
```
### Complex Derived with `$derived.by`
```svelte
<script lang="ts">
let items = $state([1, 2, 3, 4, 5]);
let filter = $state('all');
// Use $derived.by for complex computations
let filtered = $derived.by(() => {
console.log('Recomputing filtered list...');
if (filter === 'even') {
return items.filter(n => n % 2 === 0);
}
if (filter === 'odd') {
return items.filter(n => n % 2 !== 0);
}
return items;
});
</script>
```
### Derived from Multiple Sources
```svelte
<script lang="ts">
let firstName = $state('John');
let lastName = $state('Doe');
let fullName = $derived(`${firstName} ${lastName}`);
let initials = $derived(`${firstName[0]}${lastName[0]}`);
</script>
```
---
## ⚡ `$effect` - Side Effects
### Basic Effect
```svelte
<script lang="ts">
let count = $state(0);
$effect(() => {
// Runs when count changes
console.log(`Count is now ${count}`);
document.title = `Count: ${count}`;
});
</script>
```
### Effect with Cleanup
```svelte
<script lang="ts">
let running = $state(false);
$effect(() => {
if (!running) return;
const interval = setInterval(() => {
console.log('tick');
}, 1000);
// Cleanup function
return () => {
clearInterval(interval);
};
});
</script>
```
### `$effect.pre` - Before DOM Update
```svelte
<script lang="ts">
let messages = $state<string[]>([]);
let container: HTMLDivElement;
$effect.pre(() => {
// Runs BEFORE DOM updates
// Useful for preserving scroll position
messages; // Track dependency
if (container) {
// Save scroll position before new messages render
}
});
</script>
```
### `$effect.tracking` - Check if Reactive
```svelte
<script lang="ts">
$effect(() => {
console.log($effect.tracking()); // true
});
function regularFunction() {
console.log($effect.tracking()); // false
}
</script>
```
### `$effect.root` - Untracked Effect Scope
```svelte
<script lang="ts">
// Create effects outside component lifecycle
const cleanup = $effect.root(() => {
$effect(() => {
// This effect lives until cleanup() is called
});
return () => {
// Custom cleanup logic
};
});
// Later: cleanup();
</script>
```
---
## 🎯 `$props` - Component Props
### Basic Props
```svelte
<script lang="ts">
let { name, age }: { name: string; age: number } = $props();
</script>
<p>{name} is {age} years old</p>
```
### Optional Props with Defaults
```svelte
<script lang="ts">
interface Props {
name: string;
age?: number;
greeting?: string;
}
let {
name,
age = 18,
greeting = 'Hello'
}: Props = $props();
</script>
<p>{greeting}, {name}! You are {age}.</p>
```
### Rest Props
```svelte
<script lang="ts">
import type { HTMLButtonAttributes } from 'svelte/elements';
interface Props extends HTMLButtonAttributes {
variant?: 'primary' | 'secondary';
}
let { variant = 'primary', ...rest }: Props = $props();
</script>
<button class={variant} {...rest}>
<slot />
</button>
```
### Children as Props (Snippets)
```svelte
<script lang="ts">
import type { Snippet } from 'svelte';
interface Props {
header?: Snippet;
children: Snippet;
footer?: Snippet;
}
let { header, children, footer }: Props = $props();
</script>
<div class="card">
{#if header}
<header>{@render header()}</header>
{/if}
<main>{@render children()}</main>
{#if footer}
<footer>{@render footer()}</footer>
{/if}
</div>
```
---
## 🔄 `$bindable` - Two-Way Binding Props
### Basic Bindable
```svelte
<!-- TextInput.svelte -->
<script lang="ts">
let { value = $bindable('') }: { value?: string } = $props();
</script>
<input bind:value />
<!-- Parent.svelte -->
<script lang="ts">
import TextInput from './TextInput.svelte';
let name = $state('');
</script>
<TextInput bind:value={name} />
<p>Name: {name}</p>
```
### Bindable with Fallback
```svelte
<script lang="ts">
// Provide a fallback for when parent doesn't bind
let { checked = $bindable(false) }: { checked?: boolean } = $props();
</script>
<input type="checkbox" bind:checked />
```
---
## 🎨 `$inspect` - Development Debugging
### Basic Inspect
```svelte
<script lang="ts">
let count = $state(0);
let user = $state({ name: 'John' });
// Logs whenever count or user changes
$inspect(count, user);
</script>
```
### Custom Inspect Handler
```svelte
<script lang="ts">
let data = $state({ x: 0, y: 0 });
$inspect(data).with((type, ...values) => {
if (type === 'update') {
console.log('Data updated:', values);
}
});
</script>
```
### Breakpoint on Change
```svelte
<script lang="ts">
let buggyValue = $state(0);
// Pauses debugger when value changes
$inspect(buggyValue).with(() => {
debugger;
});
</script>
```
---
## 🏪 Class-Based State with `$state`
```svelte
<script lang="ts" module>
// Can be in a separate .svelte.ts file
export class Counter {
count = $state(0);
doubled = $derived(this.count * 2);
increment() {
this.count++;
}
decrement() {
this.count--;
}
reset() {
this.count = 0;
}
}
</script>
<script lang="ts">
const counter = new Counter();
</script>
<button onclick={() => counter.decrement()}>-</button>
<span>{counter.count} (doubled: {counter.doubled})</span>
<button onclick={() => counter.increment()}>+</button>
```
---
## ⚠️ Common Mistakes
### ❌ Wrong: Destructuring Loses Reactivity
```svelte
<script lang="ts">
let user = $state({ name: 'John', age: 30 });
// ❌ This breaks reactivity!
let { name, age } = user;
// ✅ Access properties directly
// user.name, user.age
</script>
```
### ❌ Wrong: Effect Without Dependencies
```svelte
<script lang="ts">
let count = $state(0);
// ❌ This runs only once (no reactive reads inside)
$effect(() => {
console.log('This only runs once');
});
// ✅ Read reactive values to create dependencies
$effect(() => {
console.log(`Count is ${count}`);
});
</script>
```
### ❌ Wrong: Mutating Derived Values
```svelte
<script lang="ts">
let items = $state([1, 2, 3]);
let doubled = $derived(items.map(n => n * 2));
// ❌ Cannot mutate derived values!
// doubled.push(8);
// ✅ Mutate the source
items.push(4);
</script>
```
---
## 📊 Runes Comparison Table
| Svelte 4 | Svelte 5 | Purpose |
|----------|----------|---------|
| `export let x` | `let { x } = $props()` | Props |
| `let x = 0` | `let x = $state(0)` | Reactive state |
| `$: y = x * 2` | `let y = $derived(x * 2)` | Computed |
| `$: { ... }` | `$effect(() => { ... })` | Side effects |
| `$$props` | `$props()` with rest | All props |
| `bind:value` | `$bindable()` | Two-way binding |