API
Six entry points. Everything below has TypeScript declarations
in node_modules/@jjordy/rogue/**/*.d.ts when you install.
@jjordy/rogue
The runtime. Import in any component file.
import {
signal, effect, memo, untrack, batch,
onCleanup, onMount,
createContext, provide, useContext,
defineComponent, emit,
For,
} from '@jjordy/rogue'
Reactivity
signal(initial: T): [() => T, (next: T | (prev: T) => T) => void] effect(fn: () => void): () => void— returns disposememo(fn: () => T): () => T untrack(fn: () => T): T batch(fn: () => T): T onCleanup(fn: () => void): voidonMount(fn: () => void): void— fires after render's DOM is connected
Components
-
defineComponent(name?, render, options?)—nameis optional; inferred from filename if omitted. -
emit(host, name, detail?, opts?)— dispatches aCustomEventthat bubbles + composed by default (crosses shadow boundaries). -
For({ each, by, children })— keyed list reconciliation.
Context
createContext(default): Context provide(context, value)— call inside a renderuseContext(context)— walks ancestor chain across shadow boundaries
@jjordy/rogue/router
import { useRoute, navigate, mount } from '@jjordy/rogue/router'
useRoute(): { url, params, query, data }— all signal gettersnavigate(path, opts?: { replace?: boolean; scroll?: boolean }): void— scrolls to top by default; passscroll: falsefor filter/tab UIsmount(target, opts?)— pushState + popstate + click capture; hydrates if target has SSR'd content andinitialDatais passed
@jjordy/rogue/forms
import {
useForm, defineActions,
redirect, invalid, formError,
} from '@jjordy/rogue/forms'
useForm(action, options?)— returns aFormApiwith spreaders (props,field) and reactive accessors (errors,formError,submitting,values,touched,validating) plussubmit()+reset()defineActions(map)— wraps an actions map so each entry knows its name (required for server-action dispatch)redirect(path, opts?)— return fromrun()to navigate after successinvalid({ field: message })— return to surface server-side field errorsformError(message)— return to surface a form-level error not tied to any field
See the Forms + mutations guide for the full walkthrough.
@jjordy/rogue/testing
import { setupDOM, mount, fireEvent, query, tick } from '@jjordy/rogue/testing'
setupDOM(opts?)— installs a linkedom-backed DOM on globalThis. Idempotent.mount(tag, attrs?): HTMLElementfireEvent(el, type, init?): booleanquery/queryAll(el, selector)— pierces shadow DOMtick(): Promise— drain two microtask turns
@jjordy/rogue/vite
import { rogue, rogueRouter, rogueSsr } from '@jjordy/rogue/vite'
rogue()— compiles JSX/TSX into custom-element registrationsrogueRouter()— file-system routing + per-page./codegen.types rogueSsr()— runs SSR + the server-action handler insidevite dev, sonpm run devbehaves like production (HTML rendered server-side, form POSTs dispatched). Add this if you want full SSR during development; skip it for client-only setups.
@jjordy/rogue/server
import { render, handleAction } from '@jjordy/rogue/server'
// GET request:
const { html, status } = await render(url, vite, { request })
// POST request with ?_action=:
const out = await handleAction(url, vite, request)
// out: { status, headers, body }
render(url, vite, opts?)— SSR a route.opts={ request, prefetchedData, form }. Returns{ html, status }.handleAction(url, vite, request)— dispatches an action POST. Parses FormData, runs the schema, callsaction.run(), content-negotiates JSON (with-JS) vs HTML re-render (no-JS). Returns{ status, headers, body }.