## Demo: runed ### Runed.svelte ```svelte

Runed needs no special setup — it's a plain Svelte 5 runes library, so you install it and import from runed. In Mochi it bundles straight into whichever island imports it.

Then import a utility and use it like any rune — e.g. the Debounced value driving the first card:

Explore the full toolkit at runed.dev.

Reactivity & timing

Debounced, Throttled, Previous, and watch — one input, four derived views.

State

StateHistory undo/redo, PersistedState across reloads and tabs, and IsMounted.

Elements & observers

ElementSize + useResizeObserver, IsInViewport, activeElement, and IsFocusWithin.

Sensors & animation

PressedKeys, IsIdle, and AnimationFrames with a live FPS cap.

State machine & async

A self-driving FiniteStateMachine traffic light and a debounced resource search over a Mochi API.

``` ### Reactivity.svelte ```svelte
live{text || '—'}
Debounced (400ms){debounced.current || '—'}
Throttled (400ms){throttled.current || '—'}
Previous{previous.current ?? '—'}
watch() change log {#if log.length === 0}

Waiting for the debounced value to settle…

{:else} {/if}
``` ### StateCard.svelte ```svelte

StateHistory

undo / redo any $state
{count}

{history.log.length} snapshot{history.log.length === 1 ? '' : 's'} recorded

PersistedState

localStorage · survives reload · syncs tabs
{persisted.current}

Reload the page — the value sticks. Open a second tab to watch it sync.

IsMounted

false during SSR, true after hydration
{#if isMounted.current} mounted (client) {:else} not mounted (server) {/if}
``` ### Elements.svelte ```svelte

ElementSize + useResizeObserver

drag the corner of the box
{Math.round(size.width)} × {Math.round(size.height)} {resizes} resize event{resizes === 1 ? '' : 's'}

IsInViewport

scroll the target in and out
scroll down ↓
{inViewport.current ? 'In viewport' : 'Out of viewport'}
↑ scroll up
{#if inViewport.current} visible {:else} hidden {/if}

activeElement + IsFocusWithin

tab through the fields
focused: {activeElement.current?.localName ?? 'none'} {#if focusWithin.current} focus within {/if}
``` ### Sensors.svelte ```svelte

PressedKeys

hold any keys — try Ctrl + Shift
{#if keys.all.length === 0} No keys pressed {:else} {#each keys.all as key (key)} {key} {/each} {/if}

IsIdle

stop moving the mouse for 2s
{#if idle.current} idle {:else} active {/if}

Last active: {new Date(idle.lastActive).toLocaleTimeString()}

AnimationFrames

rAF loop with an FPS cap
{Math.round(animation.fps)} fps {frames} frames
``` ### AsyncFsm.svelte ```svelte

FiniteStateMachine

_enter hooks auto-advance via .debounce()
{light.current}

resource

debounced fetch with cancellation
{#if search.loading} Loading… {:else if search.error} Error: {search.error.message} {:else} {search.current?.matches.length ?? 0} match{search.current?.matches.length === 1 ? '' : 'es'} {/if}
{#each search.current?.matches ?? [] as fruit (fruit)} {fruit} {/each}
``` ### routes.ts ```ts import { Mochi, getRequestContext } from 'mochi-framework'; import type { MochiRouteValue } from 'mochi-framework'; const FRUITS = ['apple', 'apricot', 'banana', 'blueberry', 'cherry', 'grape', 'lemon', 'mango', 'orange', 'peach', 'pear', 'plum']; export const routes: Record = { '/demos/runed': Mochi.page('./src/demos/runed/Runed.svelte'), '/api/runed/search': Mochi.api(() => { const { url } = getRequestContext(); const q = (url.searchParams.get('q') ?? '').toLowerCase(); const matches = q ? FRUITS.filter((f) => f.includes(q)) : FRUITS; return Response.json({ matches }); }), }; ``` ### index.ts ```ts import { Mochi, logger } from 'mochi-framework'; import { routes } from './routes'; await Mochi.serve({ port: 3333, development: process.env.MODE === 'development', routes, }); logger.info('Server running at http://localhost:3333'); ```