@akashjs/runtime API
Signals
signal(initialValue, options?)
Create a reactive value.
function signal<T>(initialValue: T, options?: {
equals?: (a: T, b: T) => boolean;
}): Signal<T>;Returns: Signal<T> — a callable with .set(), .update(), .peek().
computed(fn, options?)
Create a derived reactive value.
function computed<T>(fn: () => T, options?: {
equals?: (a: T, b: T) => boolean;
}): ReadonlySignal<T>;effect(fn, options?)
Run a side-effect when dependencies change.
function effect(
fn: () => void | (() => void),
options?: { render?: boolean },
): () => void; // dispose functionbatch(fn)
Batch signal updates to prevent intermediate effects.
function batch<T>(fn: () => T): T;flushSync()
Synchronously flush all pending effects.
function flushSync(): void;untrack(fn)
Read signals without tracking dependencies.
function untrack<T>(fn: () => T): T;Components
defineComponent(setup)
Define a component from a setup function.
function defineComponent<P extends Record<string, unknown>>(
setup: (ctx: ComponentContext<P>) => () => AkashNode,
): Component<P>;onMount(fn)
Register a mount callback. May return a cleanup function.
function onMount(fn: () => void | (() => void)): void;onUnmount(fn)
Register an unmount callback.
function onUnmount(fn: () => void): void;onError(fn)
Register an error boundary handler.
function onError(fn: (error: Error) => void): void;ref()
Create a DOM element reference.
function ref<T = HTMLElement>(): Ref<T>;Context
createContext(defaultValue?)
Create a typed context key.
function createContext<T>(defaultValue?: T): InjectionKey<T>;provide(key, value)
Provide a value to descendant components.
function provide<T>(key: InjectionKey<T>, value: T): void;inject(key, fallback?)
Inject a value from an ancestor provider.
function inject<T>(key: InjectionKey<T>): T;
function inject<T>(key: InjectionKey<T>, fallback: T): T;DOM Helpers
Show
Conditional rendering component.
function Show<T>(props: {
when: T | null | undefined | false;
fallback?: () => AkashNode;
children: (value: T) => AkashNode;
}): Node;For
List rendering component with keyed reconciliation.
function For<T>(props: {
each: T[];
key: (item: T) => unknown;
children: (item: T, index: number) => AkashNode;
}): Node;Error Catalog
formatError(code, context?)
Format an error message with code, hint, and doc link.
akashError(code, context?)
Create an Error with a formatted message.
getErrorDef(code)
Look up an error definition by code.
getAllErrorCodes()
Get all registered error codes.
Store
defineStore(id, config)
Create a reactive store.
function defineStore<S, G, A>(
id: string,
config: {
state: () => S;
getters?: G & Record<string, (state: S) => unknown>;
actions?: A & Record<string, (...args: any[]) => unknown>;
},
): () => Store<S, G, A>;Returns: a composable that returns the store instance. The store provides:
$id— the store identifier string.$reset()— reset state to initial values.$snapshot()— return a plain copy of current state.$subscribe(callback)— listen for state changes. Returns an unsubscribe function.
clearStores()
Dispose all active stores. Useful for SSR or testing.
function clearStores(): void;Transitions
Transition
Component that applies enter/exit CSS transitions to its child.
function Transition(props: {
name?: string;
enterFrom?: string;
enterTo?: string;
exitFrom?: string;
exitTo?: string;
duration?: number;
children: () => AkashNode;
}): Node;getTransitionClasses(name, phase)
Return the class names for a transition phase.
function getTransitionClasses(name: string, phase: 'enter' | 'exit'): {
from: string;
active: string;
to: string;
};enterTransition(el, classes, duration?)
Apply enter transition to an element. Returns a promise that resolves when complete.
function enterTransition(el: HTMLElement, classes: TransitionClasses, duration?: number): Promise<void>;exitTransition(el, classes, duration?)
Apply exit transition to an element. Returns a promise that resolves when complete.
function exitTransition(el: HTMLElement, classes: TransitionClasses, duration?: number): Promise<void>;generateTransitionCSS(name, options?)
Generate CSS keyframe rules for a named transition.
function generateTransitionCSS(name: string, options?: {
duration?: number;
easing?: string;
}): string;Head Management
useHead(config)
Set document head tags reactively. Supports title, meta, link, and script tags.
function useHead(config: {
title?: string | (() => string);
meta?: Array<Record<string, string>>;
link?: Array<Record<string, string>>;
script?: Array<Record<string, string>>;
}): void;renderHeadToString()
Render collected head tags to an HTML string for SSR.
function renderHeadToString(): string;collectSSRHead()
Collect head configuration during server-side rendering. Returns raw tag objects.
function collectSSRHead(): HeadTag[];Plugins
definePlugin(config)
Define a plugin that can extend the application.
function definePlugin(config: {
name: string;
setup: (app: App) => void;
}): Plugin;createApp(component)
Create an application instance. Chain .use(plugin) to install plugins, then .mount(selector) to render.
function createApp(component: Component): App;
interface App {
use(plugin: Plugin): App;
mount(selector: string | HTMLElement): void;
unmount(): void;
}Composables
useInterval(ms)
Run a callback on an interval. Auto-cleans up on unmount.
function useInterval(ms: number): {
start(fn: () => void): void;
stop(): void;
isRunning: () => boolean;
};useTimeout(ms)
Schedule a callback after a delay. Auto-cleans up on unmount.
function useTimeout(ms: number): {
start(fn: () => void): void;
cancel(): void;
isPending: () => boolean;
};useDebounce(source, delay)
Create a debounced signal that updates after delay ms of inactivity.
function useDebounce<T>(source: () => T, delay: number): () => T;useThrottle(source, interval)
Create a throttled signal that updates at most once per interval ms.
function useThrottle<T>(source: () => T, interval: number): () => T;useCounter(initial?)
Reactive counter with convenience methods.
function useCounter(initial?: number): {
count: () => number;
increment(): void;
decrement(): void;
set(value: number): void;
reset(): void;
};useToggle(initial?)
Reactive boolean toggle.
function useToggle(initial?: boolean): {
value: () => boolean;
toggle(): void;
setTrue(): void;
setFalse(): void;
};usePrevious(source)
Track the previous value of a reactive source.
function usePrevious<T>(source: () => T): () => T | undefined;Browser APIs
useMediaQuery(query)
Reactive media query match.
function useMediaQuery(query: string): () => boolean;useBreakpoint(breakpoints?)
Reactive viewport breakpoint. Uses sensible defaults if no breakpoints provided.
function useBreakpoint(breakpoints?: Record<string, number>): {
current: () => string;
matches: (bp: string) => boolean;
};useStorage(key, initial, storage?)
Two-way binding to localStorage or sessionStorage.
function useStorage<T>(
key: string,
initial: T,
storage?: Storage,
): Signal<T>;useClipboard()
Read and write the system clipboard.
function useClipboard(): {
text: () => string;
copied: () => boolean;
copy(value: string): Promise<void>;
};useOnline()
Reactive network status.
function useOnline(): () => boolean;useGeolocation()
Reactive geolocation.
function useGeolocation(): {
coords: () => GeolocationCoordinates | null;
error: () => GeolocationPositionError | null;
loading: () => boolean;
};useWindowSize()
Reactive window dimensions.
function useWindowSize(): {
width: () => number;
height: () => number;
};useClickOutside(target, handler, options?)
Detect clicks outside an element. Returns a dispose function.
function useClickOutside(
target: HTMLElement | (() => HTMLElement | null),
handler: (event: Event) => void,
options?: {
events?: string[]; // default: ['pointerdown']
ignore?: (string | HTMLElement)[]; // selectors/elements to ignore
active?: boolean; // default: true
},
): () => void;Portal
Portal
Render children into a different DOM target.
function Portal(props: {
target: string | HTMLElement;
children: () => AkashNode;
}): Node;target can be a CSS selector string or an element reference.
Toast
createToaster(options?)
Create a toast notification system.
function createToaster(options?: {
position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
duration?: number;
max?: number;
}): Toaster;
interface Toaster {
success(message: string): string;
error(message: string): string;
info(message: string): string;
warning(message: string): string;
dismiss(id: string): void;
dismissAll(): void;
}Each method (except dismiss/dismissAll) returns a toast ID.
Theme
useTheme(config?)
Reactive theme management. Persists selection to storage.
function useTheme(config?: {
themes?: string[];
defaultTheme?: string;
storageKey?: string;
}): {
current: () => string;
set(theme: string): void;
toggle(): void;
isDark: () => boolean;
themes: string[];
};Virtual List
VirtualFor
Virtualized list component for rendering large datasets efficiently.
function VirtualFor<T>(props: {
each: T[];
key: (item: T) => unknown;
itemHeight: number;
overscan?: number;
children: (item: T, index: number) => AkashNode;
}): Node;calculateRange(scrollTop, viewportHeight, itemHeight, total, overscan?)
Calculate the visible index range for virtual scrolling.
function calculateRange(
scrollTop: number,
viewportHeight: number,
itemHeight: number,
total: number,
overscan?: number,
): { start: number; end: number };useVirtualList(config)
Low-level composable for custom virtual list implementations.
function useVirtualList(config: {
itemCount: () => number;
itemHeight: number;
overscan?: number;
}): {
containerRef: Ref<HTMLElement>;
visibleRange: () => { start: number; end: number };
totalHeight: () => number;
offsetY: () => number;
};Async Components
defineAsyncComponent(loader | options)
Define a component that is loaded asynchronously.
function defineAsyncComponent<P>(
loader: () => Promise<{ default: Component<P> }>,
): Component<P>;
function defineAsyncComponent<P>(options: {
loader: () => Promise<{ default: Component<P> }>;
loading?: Component;
error?: Component<{ error: Error }>;
delay?: number;
timeout?: number;
}): Component<P>;Performance
startProfiling() / stopProfiling()
Toggle runtime performance profiling.
function startProfiling(): void;
function stopProfiling(): ProfileData;measureSync(label, fn)
Measure synchronous execution time.
function measureSync<T>(label: string, fn: () => T): T;measureAsync(label, fn)
Measure asynchronous execution time.
function measureAsync<T>(label: string, fn: () => Promise<T>): Promise<T>;createTimer()
Create a manual timer for custom measurements.
function createTimer(): {
start(): void;
stop(): number; // elapsed ms
elapsed(): number;
};formatProfile(data)
Format profiling data into a human-readable string.
function formatProfile(data: ProfileData): string;Leak Detection
enableLeakDetection()
Enable tracking of signal/effect allocations for leak detection.
function enableLeakDetection(): void;checkForLeaks()
Check for undisposed signals or effects. Returns detected leaks.
function checkForLeaks(): LeakReport;reportLeaks()
Print leak report to console. Returns the number of leaks found.
function reportLeaks(): number;Accessibility
useFocusTrap(container, options?)
Trap keyboard focus within a container element. Useful for modals, dialogs, and drawers.
function useFocusTrap(
container: Ref<HTMLElement> | HTMLElement,
options?: FocusTrapOptions,
): { activate: () => void; deactivate: () => void; active: () => boolean };
interface FocusTrapOptions {
initialFocus?: string | HTMLElement;
returnFocus?: boolean;
escapeDeactivates?: boolean;
allowOutsideClick?: boolean;
onDeactivate?: () => void;
}useAnnounce()
Create a live-region announcer for screen readers.
function useAnnounce(): (message: string, politeness?: AriaLive) => void;
type AriaLive = 'polite' | 'assertive' | 'off';useKeyboard()
Manage keyboard shortcuts with scoping and conflict resolution.
function useKeyboard(): KeyboardManager;
interface KeyboardManager {
bind(key: string, handler: (e: KeyboardEvent) => void, options?: { scope?: string; preventDefault?: boolean }): () => void;
enableScope(scope: string): void;
disableScope(scope: string): void;
getBindings(): Map<string, Function[]>;
dispose(): void;
}Image
Image
Optimized image component with lazy loading, placeholder support, and fallback handling.
function Image(props: ImageProps): Node;
interface ImageProps {
src: string;
alt: string;
width?: number;
height?: number;
loading?: 'lazy' | 'eager';
srcset?: string;
sizes?: string;
placeholder?: 'blur' | 'empty';
blurDataUrl?: string;
class?: string;
fallbackSrc?: string;
onLoad?: () => void;
onError?: (error: Event) => void;
}Infinite Scroll
useInfiniteScroll(options)
Observe a sentinel element to trigger loading more items as the user scrolls.
function useInfiniteScroll(options: InfiniteScrollOptions): {
sentinel: Ref<HTMLElement>;
loading: () => boolean;
done: () => boolean;
reset: () => void;
dispose: () => void;
};
interface InfiniteScrollOptions {
onLoadMore: () => Promise<void>;
hasMore: () => boolean;
rootMargin?: string;
threshold?: number;
}CSS Utilities
cx(...inputs)
Merge class names, filtering out falsy values. Accepts strings, arrays, and objects.
function cx(...inputs: Array<string | false | null | undefined | Record<string, boolean>>): string;css(styles)
Convert a style object to a CSS string.
function css(styles: Record<string, string | number>): string;applyStyles(el, styles)
Apply a style object directly to an element.
function applyStyles(el: HTMLElement, styles: Record<string, string | number>): void;Dependency Injection
defineProvider(config)
Define a provider with a factory and scope.
function defineProvider<T>(config: {
factory: () => T;
providedIn?: 'root' | 'component';
}): Provider<T>;createInjector(bindings, parent?)
Create an injector with explicit bindings. Optionally inherit from a parent injector.
function createInjector(
bindings: Array<
| { provide: Token<T>; useFactory: () => T }
| { provide: Token<T>; useValue: T }
| { provide: Token<T>; useExisting: Token<T> }
>,
parent?: Injector,
): Injector;injectProvider(token)
Resolve a provider from the nearest injector in the component tree.
function injectProvider<T>(token: Token<T>): T;clearProviders()
Clear all root-level provider instances. Useful for testing and SSR.
function clearProviders(): void;Animations
animate(element, options)
Animate an element using the Web Animations API.
function animate(element: HTMLElement, options: {
properties: Record<string, [string, string]> | Keyframe[];
duration?: number;
easing?: string;
delay?: number;
fill?: FillMode;
iterations?: number;
direction?: PlaybackDirection;
}): AnimationControl;animateStagger(elements, options)
Animate a list of elements with staggered delay.
function animateStagger(
elements: NodeListOf<Element> | Element[],
options: AnimateOptions & {
stagger: number;
from?: 'start' | 'center' | 'end';
},
): Promise<void>;animateSequence(steps)
Run animations sequentially. Each step waits for the previous to finish.
function animateSequence(
steps: Array<{ element: HTMLElement } & AnimateOptions>,
): Promise<void>;animateGroup(steps)
Run multiple animations in parallel, resolving when all complete.
function animateGroup(
steps: Array<{ element: HTMLElement } & AnimateOptions>,
): Promise<void>;animateSpring(element, options)
Physics-based spring animation.
function animateSpring(element: HTMLElement, options: {
properties: Record<string, [string, string]>;
stiffness?: number;
damping?: number;
mass?: number;
}): AnimationControl;keyframes(frames)
Create a multi-step keyframe array for use with animate().
function keyframes(
frames: Array<{ offset: number } & Record<string, string | number>>,
): Keyframe[];defineStates(element, config)
Create a state-based animation machine.
function defineStates(element: HTMLElement, config: {
states: Record<string, Record<string, string | number>>;
transitions: {
duration: number;
easing?: string;
overrides?: Record<string, { duration?: number; easing?: string }>;
};
initial: string;
}): {
go(state: string): Promise<void>;
current(): string;
onTransition(cb: (from: string, to: string) => void): () => void;
};Defer
defer(loader, options)
Defer loading of a component until a trigger condition is met.
function defer<T>(
loader: () => Promise<{ default: T }>,
options: DeferOptions,
): T;
interface DeferOptions {
trigger: DeferTrigger;
loading?: () => AkashNode;
error?: (err: Error) => AkashNode;
prefetch?: boolean;
minimumLoadTime?: number;
}
type DeferTrigger =
| 'viewport'
| 'interaction'
| 'idle'
| 'hover'
| { type: 'viewport'; rootMargin?: string; threshold?: number }
| { type: 'interaction'; events?: string[] }
| { type: 'timer'; delay: number }
| { type: 'custom'; when: () => boolean };View Transitions
startViewTransition(callback, options?)
Start a view transition. Falls back gracefully when the API is unsupported.
function startViewTransition(
callback: () => void | Promise<void>,
options?: {
fallback?: 'none' | 'fade';
duration?: number;
onStart?: () => void;
onFinish?: () => void;
},
): Promise<void>;supportsViewTransitions()
Check whether the browser supports the View Transitions API.
function supportsViewTransitions(): boolean;viewTransitionCSS(config)
Generate CSS rules for view transition pseudo-elements.
function viewTransitionCSS(config: {
name?: string;
old: Record<string, string>;
new: Record<string, string>;
}): string;assignTransitionName(element, name)
Assign a view-transition-name CSS property to an element.
function assignTransitionName(element: HTMLElement, name: string): void;Data Table
createDataTable(options)
Create a reactive data table with sorting, filtering, column visibility, and pagination.
function createDataTable<T>(options: {
data: () => T[];
columns: ColumnDef<T>[];
pageSize?: number;
}): {
rows: () => T[];
columns: () => ColumnDef<T>[];
sortState: () => SortState;
page: () => number;
pageCount: () => number;
sort(columnId: string): void;
filter(columnId: string, value: string): void;
toggleColumn(columnId: string): void;
nextPage(): void;
prevPage(): void;
goToPage(page: number): void;
reset(): void;
};
interface ColumnDef<T> {
id: string;
header: string;
accessor: (row: T) => unknown;
sortable?: boolean;
filterable?: boolean;
visible?: boolean;
}
interface SortState {
columnId: string | null;
direction: 'asc' | 'desc';
}SEO
useSEO(config)
Set common SEO meta tags reactively (title, description, canonical, robots).
function useSEO(config: {
title?: string | (() => string);
description?: string | (() => string);
canonical?: string;
robots?: string;
}): void;useStructuredData(data)
Inject JSON-LD structured data into the document head.
function useStructuredData(data: Record<string, unknown>): void;useOpenGraph(data)
Set Open Graph meta tags.
function useOpenGraph(data: {
title?: string;
description?: string;
image?: string;
url?: string;
type?: string;
siteName?: string;
}): void;useTwitterCard(data)
Set Twitter Card meta tags.
function useTwitterCard(data: {
card?: 'summary' | 'summary_large_image' | 'app' | 'player';
site?: string;
creator?: string;
title?: string;
description?: string;
image?: string;
}): void;generateSitemap(baseUrl, entries)
Generate a sitemap XML string from a list of URL entries.
function generateSitemap(
baseUrl: string,
entries: Array<{
path: string;
lastmod?: string;
changefreq?: string;
priority?: number;
}>,
): string;Watchers
watch(source, callback, options?)
Watch a reactive source and invoke a callback with the new and previous values whenever it changes.
function watch<T>(
source: WatchSource<T>,
callback: WatchCallback<T>,
options?: WatchOptions,
): () => void;
// Multiple sources:
function watch<T extends unknown[]>(
sources: { [K in keyof T]: WatchSource<T[K]> },
callback: (newValues: T, oldValues: (T[number] | undefined)[]) => void,
options?: WatchOptions,
): () => void;
type WatchSource<T> = () => T;
type WatchCallback<T> = (newValue: T, oldValue: T | undefined) => void;Returns: a dispose function.
WatchOptions
| Option | Type | Default | Description |
|---|---|---|---|
immediate | boolean | false | Run callback immediately with the current value |
once | boolean | false | Fire once then auto-dispose |
debounce | number | undefined | Debounce the callback in ms |
deep | boolean | false | Deep comparison for objects |
watchOnce(source, callback)
Convenience wrapper — watches a source once with immediate: true, then auto-disposes.
function watchOnce<T>(
source: WatchSource<T>,
callback: WatchCallback<T>,
): () => void;watchDebounced(source, callback, ms)
Convenience wrapper — watches with built-in debounce.
function watchDebounced<T>(
source: WatchSource<T>,
callback: WatchCallback<T>,
ms: number,
): () => void;Deep Signals
deepSignal(initialValue)
Create a deeply reactive signal. Nested property access is tracked, and setting any nested property triggers updates.
function deepSignal<T extends object>(initialValue: T): DeepSignal<T>;
type DeepSignal<T> = T extends object
? { [K in keyof T]: DeepSignal<T[K]> } & { readonly $raw: T; readonly $signal: () => T }
: T;The returned proxy supports reading, writing, and deleting nested properties — all reactive. Use $raw to get a plain snapshot and $signal to read the whole object as a tracked signal.
toRaw(proxy)
Get the raw (unwrapped) value from a deep signal.
function toRaw<T>(proxy: DeepSignal<T>): T;isDeepSignal(value)
Check whether a value is a deep signal proxy.
function isDeepSignal(value: unknown): boolean;State Machine
createMachine(config)
Create a finite state machine with typed states, events, guards, actions, and reactive current state.
function createMachine<
TState extends string,
TEvent extends string,
TContext = unknown,
>(config: MachineConfig<TState, TEvent, TContext>): Machine<TState, TEvent, TContext>;MachineConfig
interface MachineConfig<TState extends string, TEvent extends string, TContext = unknown> {
initial: TState;
context?: TContext;
states: Record<TState, StateConfig<TState, TEvent, TContext>>;
}StateConfig
interface StateConfig<TState extends string, TEvent extends string, TContext = unknown> {
on?: Partial<Record<TEvent, TState | TransitionConfig<TState, TEvent, TContext>>>;
entry?: (ctx: MachineContext<TContext>) => void;
exit?: (ctx: MachineContext<TContext>) => void;
type?: 'final';
}TransitionConfig (guards and actions)
interface TransitionConfig<TState extends string, TEvent extends string, TContext = unknown> {
target: TState;
guard?: (ctx: MachineContext<TContext>) => boolean;
action?: (ctx: MachineContext<TContext>) => void;
}MachineContext
interface MachineContext<TContext> {
data: TContext;
event: string;
}Machine
interface Machine<TState extends string, TEvent extends string, TContext = unknown> {
state: ReadonlySignal<TState>;
context: ReadonlySignal<TContext>;
send(event: TEvent, payload?: Record<string, unknown>): void;
matches(state: TState): boolean;
done: ReadonlySignal<boolean>;
reset(): void;
history: ReadonlySignal<TState[]>;
can(event: TEvent): boolean;
nextEvents: ReadonlySignal<TEvent[]>;
}Event Bus
createEventBus()
Create a typed event bus for cross-component pub/sub communication.
function createEventBus<T extends EventMap = Record<string, unknown>>(): EventBus<T>;
type EventMap = Record<string, unknown>;
type EventHandler<T = unknown> = (data: T) => void;
interface EventBus<T extends EventMap> {
on<K extends keyof T & string>(event: K, handler: EventHandler<T[K]>): () => void;
once<K extends keyof T & string>(event: K, handler: EventHandler<T[K]>): () => void;
emit<K extends keyof T & string>(event: K, data: T[K]): void;
off<K extends keyof T & string>(event: K, handler: EventHandler<T[K]>): void;
clear(event?: keyof T & string): void;
listenerCount(event: keyof T & string): number;
hasListeners(event: keyof T & string): boolean;
}globalEventBus()
Get (or create) the global event bus singleton. Useful for app-wide events without passing a bus instance around.
function globalEventBus<T extends EventMap = Record<string, unknown>>(): EventBus<T>;Tweened Signals
tweened(initialValue, options?)
Create a signal that smoothly animates between values over time.
function tweened<T>(initialValue: T, options?: TweenedOptions<T>): TweenedSignal<T>;
interface TweenedOptions<T> {
duration?: number; // ms, default 400
easing?: EasingFn; // default cubicOut
interpolate?: Interpolator<T>;
delay?: number;
}
interface TweenedSignal<T> {
(): T; // read current (animated) value
set(value: T, opts?: Partial<TweenedOptions<T>>): Promise<void>; // animate to new value
setImmediate(value: T): void; // jump without animation
target: () => T; // current target value
}
type EasingFn = (t: number) => number;
type Interpolator<T> = (from: T, to: T, t: number) => T;easings
Built-in easing functions: linear, cubicIn, cubicOut, cubicInOut, quadIn, quadOut, quintOut, bounceOut, elasticOut.
import { easings } from '@akashjs/runtime';
const x = tweened(0, { easing: easings.bounceOut });FLIP Animations
createFlip(container, options?)
Create a FLIP animation controller for smooth list reordering.
function createFlip(container: HTMLElement, options?: FlipOptions): FlipController;
interface FlipOptions {
duration?: number; // default 300
easing?: string; // CSS easing, default 'cubic-bezier(0.2, 0, 0, 1)'
delay?: number;
selector?: string; // only animate matching children
keyAttribute?: string; // default 'data-key'
onComplete?: () => void;
}
interface FlipController {
measure(): void; // call BEFORE DOM change
animate(): Promise<void>; // call AFTER DOM change
flip(update: () => void): Promise<void>; // measure + update + animate in one step
}flip(container, update, options?)
One-shot helper that creates a controller, measures, runs the update, and animates.
function flip(
container: HTMLElement,
update: () => void,
options?: FlipOptions,
): Promise<void>;Await
Await
Component for declarative promise handling — renders different content for pending, resolved, and rejected states.
function Await<T>(props: AwaitProps<T>): Node;
interface AwaitProps<T> {
promise: Promise<T>;
pending?: () => AkashNode;
then: (value: T) => AkashNode;
catch?: (error: Error) => AkashNode;
}awaitSignal(promise)
Functional helper that wraps a promise into a reactive signal tracking its state.
function awaitSignal<T>(
promise: Promise<T>,
): () => { status: 'pending' } | { status: 'resolved'; value: T } | { status: 'rejected'; error: Error };Event Modifiers and Bind Directives
withModifiers(handler, modifiers)
Wrap an event handler with modifiers (preventDefault, stopPropagation, once, self, capture, passive).
function withModifiers<E extends Event>(
handler: (e: E) => void,
modifiers: EventModifiers,
): (e: E) => void;
interface EventModifiers {
preventDefault?: boolean;
stopPropagation?: boolean;
stopImmediatePropagation?: boolean;
once?: boolean;
capture?: boolean;
passive?: boolean;
self?: boolean;
}onEvent(el, event, handler, modifiers?)
Attach an event handler with modifiers to an element. Returns a dispose function.
function onEvent<K extends keyof HTMLElementEventMap>(
el: HTMLElement,
event: K,
handler: (e: HTMLElementEventMap[K]) => void,
modifiers?: EventModifiers,
): () => void;bindDimensions(el)
Bind element dimensions (clientWidth/clientHeight) to reactive read-only signals using ResizeObserver.
function bindDimensions(el: HTMLElement): {
width: ReadonlySignal<number>;
height: ReadonlySignal<number>;
};bindScroll(el?)
Bind scroll position to read/write signals. Omit el to bind to the window.
function bindScroll(el?: HTMLElement): {
scrollX: Signal<number>;
scrollY: Signal<number>;
};bindElement()
Create a signal that holds an element reference (like bind:this in Svelte).
function bindElement<T extends HTMLElement = HTMLElement>(): Signal<T | null>;bindGroup(name)
Create a signal for a radio/checkbox group.
function bindGroup<T>(name: string): Signal<T | null>;bindGroupItem(el, group, value)
Bind an individual radio/checkbox input to a group signal.
function bindGroupItem<T>(el: HTMLInputElement, group: Signal<T | null>, value: T): void;bindClass(el, className, condition)
Reactively toggle a CSS class based on a condition.
function bindClass(el: HTMLElement, className: string, condition: () => boolean): () => void;bindClasses(el, classes)
Apply multiple conditional CSS classes at once.
function bindClasses(el: HTMLElement, classes: Record<string, () => boolean>): () => void;bindStyle(el, property, value)
Reactively bind a single CSS property.
function bindStyle(el: HTMLElement, property: string, value: () => string | number | null): () => void;bindStyles(el, styles)
Bind multiple CSS properties at once.
function bindStyles(el: HTMLElement, styles: Record<string, () => string | number | null>): () => void;Snippets and Utilities
defineSnippet(render)
Define a reusable template snippet (a function that returns a renderable node).
function defineSnippet<TArgs extends unknown[]>(
render: (...args: TArgs) => AkashNode,
): Snippet<TArgs>;
type Snippet<TArgs extends unknown[] = []> = (...args: TArgs) => AkashNode;inspect(...sources, options?)
Debug helper that logs reactive values whenever they change.
function inspect(
...args: [...Array<() => unknown>, InspectOptions?]
): () => void;
interface InspectOptions {
label?: string; // prefix (default: 'inspect')
level?: 'log' | 'warn' | 'debug' | 'trace';
logger?: (label: string, ...values: unknown[]) => void;
when?: () => boolean; // only log when condition is true
}defineFormAction(url, options?)
Define a server-side form action with progressive enhancement.
function defineFormAction<T = unknown>(
url: string,
options?: {
method?: 'POST' | 'PUT' | 'PATCH' | 'DELETE';
headers?: Record<string, string>;
onSuccess?: (result: T) => void;
onError?: (error: Error) => void;
fetch?: typeof globalThis.fetch;
},
): FormAction<T>;
interface FormAction<T = unknown> {
url: string;
method: 'POST' | 'PUT' | 'PATCH' | 'DELETE';
submitting: ReadonlySignal<boolean>;
result: ReadonlySignal<T | null>;
error: ReadonlySignal<Error | null>;
handle(formData?: Record<string, unknown>): (e: Event) => void;
submit(data: Record<string, unknown>): Promise<T>;
}enableSnapshots(config?)
Enable navigation snapshots — preserves scroll position and form state across back/forward navigation.
function enableSnapshots(config?: SnapshotConfig): () => void;
interface SnapshotConfig {
keyPrefix?: string; // default 'akash-snapshot'
capture?: ('scroll' | 'forms')[]; // default ['scroll', 'forms']
}Query State
useQueryState(key, defaultValue, options?)
Create a signal that automatically syncs to a URL query parameter. Changes update the URL; browser back/forward updates the signal.
function useQueryState<T>(
key: string,
defaultValue: T,
options?: QueryStateOptions<T>,
): Signal<T>;
interface QueryStateOptions<T> {
serialize?: (value: T) => string;
deserialize?: (raw: string) => T;
history?: 'push' | 'replace'; // default 'replace'
debounce?: number; // ms, default 0
removeDefault?: boolean; // default true
}useQueryStates(schema, options?)
Create multiple URL-synced signals at once.
function useQueryStates<T extends QueryStateSchema>(
schema: T,
options?: { history?: 'push' | 'replace' },
): { [K in keyof T]: Signal<T[K]['default']> };clearQueryState()
Remove all query state params from the URL and reset signals to defaults.
function clearQueryState(): void;getQueryParams()
Get all current query params as a plain Record<string, string>.
function getQueryParams(): Record<string, string>;Security
sanitize(html, options?)
Strip dangerous HTML and return a safe string.
function sanitize(html: string, options?: {
allowTags?: string[];
allowAttrs?: string[];
allowStyle?: boolean;
}): string;escapeHtml(str)
Escape HTML entities in a string (&, <, >, ", ').
function escapeHtml(str: string): string;createSafeHTML(el)
Return a setter that auto-sanitizes HTML before assigning to innerHTML.
function createSafeHTML(el: HTMLElement): (html: string) => void;generateCSP(directives?)
Generate a Content-Security-Policy header value with a cryptographic nonce.
function generateCSP(directives?: Record<string, string[]>): {
header: string;
nonce: string;
};getCSPHeaderName(reportOnly?)
Return the correct CSP header name.
function getCSPHeaderName(reportOnly?: boolean): string;
// 'Content-Security-Policy' or 'Content-Security-Policy-Report-Only'generateSecurityHeaders(options?)
Return a record of recommended security headers.
function generateSecurityHeaders(options?: {
hsts?: boolean;
frameOptions?: 'DENY' | 'SAMEORIGIN';
permissionsPolicy?: Record<string, string>;
}): Record<string, string>;safeMerge(target, ...sources)
Deep-merge objects while blocking prototype pollution keys (__proto__, constructor, prototype).
function safeMerge<T>(target: T, ...sources: Partial<T>[]): T;deepFreeze(obj)
Recursively freeze an object and all nested objects.
function deepFreeze<T extends object>(obj: T): Readonly<T>;generateSRI(content, algorithm?)
Compute a Subresource Integrity hash.
function generateSRI(content: string, algorithm?: 'sha256' | 'sha384' | 'sha512'): Promise<string>;generateCSRFToken()
Generate a cryptographically random CSRF token.
function generateCSRFToken(): string;createCSRFInterceptor(options?)
Create an HTTP interceptor that attaches CSRF tokens to mutating requests.
function createCSRFInterceptor(options?: {
source?: 'meta' | 'cookie';
cookieName?: string;
headerName?: string;
}): HttpInterceptor;sanitizeURL(url, options?)
Validate and sanitize a URL, blocking dangerous schemes.
function sanitizeURL(url: string, options?: {
allowedSchemes?: string[];
allowedHosts?: string[];
}): string;createRateLimiter(options)
Create a client-side rate limiter.
function createRateLimiter(options: {
maxRequests: number;
windowMs: number;
}): {
allow(): boolean;
remaining(): number;
reset(): void;
};