API Reference
API Reference
Section titled “API Reference”Documentação completa de todas as funções, componentes e tipos exportados pelo Slash.
Instalação
Section titled “Instalação”bun add @ezbug/slash# ounpm install @ezbug/slashRenderização
Section titled “Renderização”Cria elementos DOM usando hyperscript.
function h( tag: string | Function, props?: Props | null, ...children: Child[]): VNodeParâmetros:
tag: Nome da tag HTML ou componente funcionalprops: Propriedades do elemento (opcional)children: Filhos do elemento (podem ser strings, números, VNodes, arrays)
Retorna: VNode - Representação virtual do elemento
Exemplo:
import { h } from '@ezbug/slash'
const element = h('div', { class: 'container' }, h('h1', null, 'Hello'), h('p', null, 'World'))Template tag que converte template strings em VNodes usando HTM.
const html: HTMTemplateUso:
import { html } from '@ezbug/slash'
const element = html` <div class="container"> <h1>Hello</h1> <p>World</p> </div>`Interpolação:
const name = 'John'const items = ['a', 'b', 'c']
const element = html` <div> <h1>Hello ${name}</h1> <ul> ${items.map(item => html`<li>${item}</li>`)} </ul> </div>`render()
Section titled “render()”Monta um VNode no DOM.
function render( vnode: VNode, container: HTMLElement): voidParâmetros:
vnode: VNode para renderizarcontainer: Elemento DOM onde montar
Exemplo:
import { html, render } from '@ezbug/slash'
const App = html`<h1>My App</h1>`const root = document.getElementById('app')
if (root) { render(App, root)}destroyNode()
Section titled “destroyNode()”Remove um nó do DOM e limpa recursos.
function destroyNode(element: HTMLElement): voidParâmetros:
element: Elemento DOM para destruir
Uso:
import { destroyNode } from '@ezbug/slash'
const element = document.getElementById('my-component')if (element) { destroyNode(element)}Estado Reativo
Section titled “Estado Reativo”createState()
Section titled “createState()”Cria um estado reativo com observadores.
function createState<T>( initialValue: T, options?: StateOptions): State<T>Parâmetros:
initialValue: Valor inicial do estadooptions: Opções de configuração (opcional)
Opções:
interface StateOptions { history?: boolean // Habilita histórico (time-travel debug) maxHistory?: number // Número máximo de histórico (padrão: 50)}Retorna: Objeto State<T> com métodos:
state.get()
Section titled “state.get()”Retorna o valor atual do estado.
get(): TExemplo:
const count = createState(0)console.log(count.get()) // 0state.set()
Section titled “state.set()”Atualiza o valor do estado e notifica observadores.
set(newValue: T): voidExemplo:
const count = createState(0)count.set(5)console.log(count.get()) // 5state.watch()
Section titled “state.watch()”Registra um observador que é chamado quando o estado muda.
watch(callback: (newValue: T, oldValue: T) => void): () => voidParâmetros:
callback: Função chamada ao mudar estado
Retorna: Função de cleanup para remover o observador
Exemplo:
const count = createState(0)
const unwatch = count.watch((newVal, oldVal) => { console.log(`Changed from ${oldVal} to ${newVal}`)})
count.set(5) // Logs: "Changed from 0 to 5"
// Remover observadorunwatch()Exemplo Completo:
import { createState, html } from '@ezbug/slash'
const count = createState(0, { history: true })
// Componente que usa estadoconst Counter = () => { const value = count.get()
return html` <div> <p>Count: ${value}</p> <button onclick=${() => count.set(value + 1)}> Increment </button> </div> `}batch()
Section titled “batch()”Agrupa múltiplas atualizações de estado em um único ciclo de renderização.
function batch(fn: () => void): voidParâmetros:
fn: Função que contém as atualizações
Exemplo:
import { createState, batch } from '@ezbug/slash'
const name = createState('')const age = createState(0)
// Sem batch: 2 rendersname.set('John')age.set(30)
// Com batch: 1 renderbatch(() => { name.set('John') age.set(30)})Server-Side Rendering
Section titled “Server-Side Rendering”renderToString()
Section titled “renderToString()”Renderiza um VNode para string HTML (síncrono).
function renderToString(vnode: VNode): stringParâmetros:
vnode: VNode para renderizar
Retorna: String HTML
Exemplo:
import { html, renderToString } from '@ezbug/slash'
const App = html`<h1>Hello SSR</h1>`const htmlString = renderToString(App)
console.log(htmlString) // "<h1>Hello SSR</h1>"renderToStream()
Section titled “renderToStream()”Renderiza um VNode para stream (para grandes páginas).
function renderToStream(vnode: VNode): ReadableStreamParâmetros:
vnode: VNode para renderizar
Retorna: ReadableStream que pode ser pipeado
Exemplo (Node.js):
import { html, renderToStream } from '@ezbug/slash'import { Writable } from 'stream'
const App = html`<h1>Hello Streaming</h1>`const stream = renderToStream(App)
response.writeHead(200, { 'Content-Type': 'text/html' })stream.pipe(response)htmlString
Section titled “htmlString”Template tag para criar strings HTML seguras com escapamento.
const htmlString: (strings: TemplateStringsArray, ...values: any[]) => stringUso:
import { htmlString } from '@ezbug/slash'
const title = 'My Page'const html = htmlString` <!DOCTYPE html> <html> <head><title>${title}</title></head> <body> <div id="app"></div> </body> </html>`Universal Data Loading
Section titled “Universal Data Loading”createLoader()
Section titled “createLoader()”Cria um loader isomórfico para data fetching.
function createLoader<T, Args extends any[] = []>( fetchFn: (...args: Args) => T | Promise<T>, options?: LoaderOptions): LoaderFunction<T, Args>Parâmetros:
fetchFn: Função que carrega os dadosoptions: Configurações do loader
Opções:
interface LoaderOptions { ttl?: number // Tempo de vida do cache (ms) key?: (...args: any[]) => string // Função para gerar chave de cache onError?: (error: Error) => void // Callback de erro staleWhileRevalidate?: boolean // Retorna cache stale enquanto revalida}Retorna: Função loader que pode ser chamada para carregar dados
Exemplo:
import { createLoader } from '@ezbug/slash'
interface User { id: string name: string}
const userLoader = createLoader<User>( async (id: string) => { const res = await fetch(`/api/users/${id}`) return res.json() }, { ttl: 5 * 60 * 1000, // 5 minutos key: (id) => `user:${id}` })
// Usoconst user = userLoader('123') // Carrega e cacheiaconst sameUser = userLoader('123') // Retorna do cacheinvalidateLoader()
Section titled “invalidateLoader()”Invalida o cache de um loader.
function invalidateLoader<T, Args extends any[]>( loader: LoaderFunction<T, Args>, ...args: Args): voidParâmetros:
loader: Loader para invalidarargs: Argumentos para gerar a chave (opcional)
Exemplo:
import { invalidateLoader } from '@ezbug/slash'
// Invalida cache específicoinvalidateLoader(userLoader, '123')
// Invalida todo o cache do loaderinvalidateLoader(userLoader)hydrateLoaderCache()
Section titled “hydrateLoaderCache()”Obtém o cache de loaders para hidratação no cliente.
function hydrateLoaderCache(): Record<string, any>Retorna: Objeto com cache de todos os loaders
Exemplo (Servidor):
import { hydrateLoaderCache } from '@ezbug/slash'
const cache = hydrateLoaderCache()
const html = htmlString` <!DOCTYPE html> <html> <head> <script> window.__LOADER_CACHE__ = ${JSON.stringify(cache)}; </script> </head> <body>...</body> </html>`isServer()
Section titled “isServer()”Detecta se o código está rodando no servidor.
function isServer(): booleanRetorna: true se no servidor, false no cliente
Exemplo:
import { isServer } from '@ezbug/slash'
if (isServer()) { // Código apenas para servidor console.log('Running on server')} else { // Código apenas para cliente console.log('Running on client')}Roteamento
Section titled “Roteamento”createRouter()
Section titled “createRouter()”Cria uma instância de router.
function createRouter(config: RouterConfig): RouterConfiguração:
interface RouterConfig { mode?: 'hash' | 'history' // Modo de navegação (padrão: 'hash') routes: RouteConfig[] // Definição de rotas scrollBehavior?: (to, from) => ScrollPosition beforeEach?: (to, from) => boolean | { redirect: string } afterEach?: (to, from) => void}
interface RouteConfig { path: string // Caminho da rota component: () => VNode | Promise<VNode> // Componente (pode ser lazy) beforeEnter?: (to, from) => boolean | { redirect: string } meta?: Record<string, any> // Metadados customizados}Exemplo:
import { createRouter } from '@ezbug/slash'
const router = createRouter({ mode: 'history', routes: [ { path: '/', component: () => import('./pages/Home') }, { path: '/users/:id', component: () => import('./pages/UserDetail'), meta: { requiresAuth: true } } ], beforeEach: (to, from) => { console.log(`Navigating to ${to.path}`) return true }})
router.init()Router Component
Section titled “Router Component”Componente que renderiza a rota atual.
function Router(props: { router: Router }): VNodeUso:
import { html, Router } from '@ezbug/slash'import { router } from './router'
const App = html` <div> <nav>...</nav> ${Router({ router })} </div>`Link Component
Section titled “Link Component”Componente para navegação client-side.
function Link(props: LinkProps): VNode
interface LinkProps { to: string | { path: string; query?: Record<string, string> } class?: string activeClass?: string children: Child | Child[]}Uso:
import { Link } from '@ezbug/slash'
const Nav = html` <nav> ${Link({ to: '/', children: 'Home' })} ${Link({ to: '/about', children: 'About' })} ${Link({ to: { path: '/users', query: { page: '1' } }, children: 'Users' })} </nav>`Router Instance Methods
Section titled “Router Instance Methods”router.push()
Section titled “router.push()”Navega para uma rota programaticamente.
push(location: string | { path: string; query?: Record<string, string> }): voidExemplo:
router.push('/about')router.push({ path: '/users', query: { page: '2' } })router.replace()
Section titled “router.replace()”Substitui a rota atual (não adiciona ao histórico).
replace(location: string | { path: string; query?: Record<string, string> }): voidrouter.back()
Section titled “router.back()”Volta uma página no histórico.
back(): voidrouter.forward()
Section titled “router.forward()”Avança uma página no histórico.
forward(): voidrouter.go()
Section titled “router.go()”Navega n páginas no histórico.
go(n: number): voidExemplo:
router.go(-2) // Volta 2 páginasrouter.go(1) // Avança 1 páginarouter.getCurrentRoute()
Section titled “router.getCurrentRoute()”Retorna a rota atual.
getCurrentRoute(): RouteInfo | null
interface RouteInfo { path: string params: Record<string, string> query: Record<string, string> meta: Record<string, any>}Error Handling
Section titled “Error Handling”ErrorBoundary
Section titled “ErrorBoundary”Componente para capturar erros em componentes filhos.
function ErrorBoundary(props: ErrorBoundaryProps): VNode
interface ErrorBoundaryProps { fallback?: (error: Error) => VNode onError?: (error: Error) => void children: VNode | VNode[]}Exemplo:
import { ErrorBoundary, html } from '@ezbug/slash'
const App = html` ${ErrorBoundary({ fallback: (error) => html` <div class="error"> <h2>Something went wrong</h2> <p>${error.message}</p> </div> `, onError: (error) => { console.error('Error caught:', error) }, children: html`<MyComponent />` })}`catchAsync()
Section titled “catchAsync()”Wrapper para funções assíncronas que captura erros.
function catchAsync<T>( fn: () => Promise<T>, onError?: (error: Error) => void): Promise<T | null>Exemplo:
import { catchAsync } from '@ezbug/slash'
const data = await catchAsync( async () => { const res = await fetch('/api/data') return res.json() }, (error) => { console.error('Fetch failed:', error) })safeRender()
Section titled “safeRender()”Renderiza um VNode com tratamento de erro.
function safeRender( vnode: VNode, onError?: (error: Error) => VNode): stringUso (SSR):
import { safeRender } from '@ezbug/slash'
const html = safeRender( App, (error) => html`<h1>Error: ${error.message}</h1>`)setupGlobalErrorHandler()
Section titled “setupGlobalErrorHandler()”Configura um handler global de erros.
function setupGlobalErrorHandler( handler: (error: Error) => void): voidExemplo:
import { setupGlobalErrorHandler } from '@ezbug/slash'
setupGlobalErrorHandler((error) => { console.error('Global error:', error) // Enviar para serviço de logging})Formulários
Section titled “Formulários”Form Helpers
Section titled “Form Helpers”interface FormHelpers<T> { values: State<T> errors: State<Partial<Record<keyof T, string>>> touched: State<Partial<Record<keyof T, boolean>>> handleSubmit: (e: Event) => void handleChange: (field: keyof T, value: any) => void handleBlur: (field: keyof T) => void reset: () => void}Exemplo de uso está na seção de Form Validation
Developer Experience
Section titled “Developer Experience”setDevMode()
Section titled “setDevMode()”Habilita/desabilita modo de desenvolvimento.
function setDevMode(enabled: boolean): voidExemplo:
import { setDevMode } from '@ezbug/slash'
setDevMode(process.env.NODE_ENV === 'development')setWarningsEnabled()
Section titled “setWarningsEnabled()”Habilita/desabilita warnings no console.
function setWarningsEnabled(enabled: boolean): voidisDevMode()
Section titled “isDevMode()”Verifica se está em modo dev.
function isDevMode(): booleanisWarningsEnabled()
Section titled “isWarningsEnabled()”Verifica se warnings estão habilitados.
function isWarningsEnabled(): booleanTipos TypeScript
Section titled “Tipos TypeScript”Representação virtual de um nó DOM.
type VNode = ElementNode | TextNode | ComponentNodePropriedades de um elemento.
interface Props { [key: string]: any class?: string style?: string | Record<string, string> onclick?: EventHandler onchange?: EventHandler // ... outros event handlers}State<T>
Section titled “State<T>”Tipo retornado por createState().
interface State<T> { get(): T set(value: T): void watch(callback: (newValue: T, oldValue: T) => void): () => void}Tipos válidos para children de elementos.
type Child = | VNode | string | number | boolean | null | undefined | Child[]Próximos Passos
Section titled “Próximos Passos”- Exemplos Práticos - Aplicações completas
- Guias Avançados - Técnicas avançadas
- Comparações - Slash vs outras libs