API Reference
Everything JAF gives you, in one list.
Most of it is injected into component scripts and needs no import; the rest names its subpath.
Available in every component
No import, no setup. effect, computed,
onMount, onNavigate, onDestroy,
storage, url, path,
unite, query, mutation,
ui and route.
Reactivity
| Call | What it does |
|---|---|
effect(fn) |
Runs fn now and again whenever anything it read changes.
Returns a dispose function; also disposed on unmount.
|
computed(getter) |
A cached derived value, read as .value. In a component,
let doubled = count * 2 usually says the same thing more
simply.
|
reactive(object) |
Makes a plain object deeply reactive. For code outside a component - the compiler does this for you inside one. |
<script>
let count = 0
effect(() => {
console.log('count is', count)
})
const doubled = computed(() => count * 2)
</script>
<p>{doubled.value}</p>
See Reactivity.
State
| Call | What it does |
|---|---|
storage(default) |
A reactive value persisted to localStorage. |
url(default) / url(key, default) |
A reactive value synced with a URL query parameter. The variable name is the key unless you give one. |
path(basePath, default, allowed?) |
The same, for a URL path segment under basePath. The base
path is required.
|
unite(ns.variable) |
Read and write a variable declared in another file. |
<script>
let theme = storage('light') // persisted
let search = url('') // ?search=...
let page = url('p', 1) // ?p=...
let count = unite(demo.counter) // from pages/demo.html
</script>
See State Management.
Stores outside a component
import { storage, persistedStore } from 'jafjs'
// One persisted value. Outside a component the key is explicit -
// inside one, the variable name is the key.
const theme = storage('theme', 'light')
theme.value = 'dark'
// A whole persisted object
const settings = persistedStore('settings', { theme: 'light', lang: 'en' }, {
storage: 'local', // 'local' | 'session'
debounce: 100,
exclude: ['temp'],
})
settings.theme = 'dark'
store is an alias for storage.
There is no persisted().
Lifecycle
| Call | What it does |
|---|---|
onMount(fn) |
Runs once the DOM and its bindings are ready. |
onNavigate(fn) |
Runs on every route change while the component stays mounted. Receives the new path. |
onDestroy(fn) |
Runs on unmount. Several callbacks run in reverse order. |
See Lifecycle.
Data fetching
const posts = query('/api/posts')
const users = query('users', '/api/users', { params: { limit: 10 } })
const custom = query('data', async () => fetch('/api').then(r => r.json()))
const create = mutation('/api/posts', { method: 'POST', invalidates: ['posts'] })
query() returns
{ data, loading, error, stale, refetch() };
mutation() returns
{ data, loading, error, mutate(input), reset() }. See
query() and
mutation().
Error handling
import { setErrorHandler, handleError } from 'jafjs'
setErrorHandler((error, info) => {
console.error(error, info.component)
})
handleError(new Error('Failed'), { component: 'MyComponent' })
One handler at a time. See Error Boundaries.
Lazy loading
import { lazy } from 'jafjs'
const heavy = lazy(() => import('./Heavy.html'))
// { load(), getComponent() }
See Lazy Loading.
Router
The router surface lives on jafjs/router.
None of it is global - a bare navigate(...) or
guards.allow(...) in a component script is a
ReferenceError.
import { navigate, navigateTo, generatePath, guards } from 'jafjs/router'
navigate('/users/123', { replace: true, data: { user } })
navigateTo('users-id', { id: '123' }) // typed, by route name
generatePath('users-id', { id: '123' }) // -> '/users/123'
guards.allow(['admins', 'editors'])
guards.add('premium')
guards.has('admins')
guards.clear()
guards.access = false // global flag
For most navigation you want none of this: an ordinary
<a href> is intercepted and routed. See
Navigation.
route
route (also window.route) is global and reactive:
route.path // '/users/123'
route.params // { id: '123' }
route.query // URLSearchParams
route.hash // '#section'
route.name // 'users-id'
route.data // whatever navigate() passed, in memory only
UI controller
ui is global. Full surface on
Overlays & UI State.
ui.modal.open(name, data?, options?) ui.modal.close(name?)
ui.modal.isOpen(name) ui.modal.data(name)
ui.drawer.open(name, data?) ui.drawer.toggle(name)
ui.popover.open(name, anchor?) ui.popover.toggle(name, anchor?)
ui.toast.show(message, options?) ui.toast.dismiss(id)
ui.confirm(message) ui.alert(message) ui.prompt(message)
ui.configure(options)
ui.page is deprecated and goes in v0.2. It
duplicated the router. Use navigate() and
route instead.
Package subpaths
| Import from | What is there |
|---|---|
jafjs |
reactive, effect, computed,
storage, store, persistedStore,
lazy, setErrorHandler,
handleError, mountComponent,
loadComponent, components
|
jafjs/router |
navigate, navigateTo,
generatePath, guards, and the rest of the router
|
jafjs/query |
query, mutation, configureQuery
|
jafjs/query/tanstack |
The TanStack Query adapter |
jafjs/reactivity |
The reactivity core on its own |
jafjs/vite |
The Vite plugins |
jafjs/entry-client |
The client bootstrap, imported for its side effect |
jafjs/builtins |
The built-in component handlers |
jafjs/ssg |
The prerenderer |
There is no provide() / inject().
provide() is stripped by the compiler and
inject() is a ReferenceError. Share state across
files with unite(), or pass props down.