Files
sigpro/docs/api/quick.md
2026-05-14 14:21:21 +02:00

5.7 KiB
Raw Blame History

SigPro Complete API Reference

Core Reactivity

$(value, localStorageKey?) Signal & Computed

Creates a reactive signal. If a function is passed, it becomes a computed signal that caches its result until dependencies change.

Usage Description
const count = $(0) Basic signal, returns a getter/setter: count() reads, count(5) writes.
const double = $( () => count() * 2 ) Computed signal updates automatically when count changes.
const stored = $('hello', 'myKey') Persisted signal reads/writes to localStorage.

Example

const count = $(0)
const double = $( () => count() * 2 )

watch(() => {
  console.log(`count = ${count()}, double = ${double()}`)
}) // logs on every change

count(5) // triggers log: count=5, double=10

watch(source, callback?) Reactive Effect

Two modes:

  1. Autotrack mode pass a function: watch(() => { /* reads signals */ })
    Automatically reruns whenever any signal read inside changes.

  2. Explicit mode pass an array of signals and a callback:
    watch([count, double], () => { ... })
    Runs the callback when any of the listed signals change. The callback receives the new values.

Both modes return a stop function that disposes the effect.

// auto mode
const stop = watch(() => console.log(count()))

// explicit mode
watch([count, double], ([newCount, newDouble]) => {
  console.log(newCount, newDouble)
})

Important

: Effects are depthaware they run in topological order, parents before children.


Components & DOM (Hyperscript)

h(tag, props, children) Create DOM Nodes

The universal builder. props can be omitted. Children can be strings, numbers, nodes, arrays, or dynamic functions.

Feature Example
Standard attributes h('div', { class: 'box', id: 'main' })
Events onClick: (e) => ... (automatically cleaned up)
Reactive attributes class: () => count() > 0 ? 'positive' : 'negative'
Twoway binding value: mySignal (works on input, textarea, select)
Refs ref: (el) => ... or ref: { current: null }
SVG support tag names like svg, circle, path sets correct namespace
Dangerous URL sanitising href / src with javascript: or data: are blocked → '#' (when XSS shield is active)

Dynamic children pass a function as a child, it will be reexecuted and the DOM patched automatically:

h('div', {}, [
  () => count() > 0 ? h('span', {}, 'positive') : h('span', {}, 'zero or negative')
])

Tag shortcuts

Tag helpers are exported from the core.

Available tags: a, abbr, article, aside, audio, b, blockquote, br, button, canvas, caption, cite, code, col, colgroup, datalist, dd, del, details, dfn, dialog, div, dl, dt, em, embed, fieldset, figcaption, figure, footer, form, h1h6, header, hr, i, iframe, img, input, ins, kbd, label, legend, li, main, mark, meter, nav, object, ol, optgroup, option, output, p, picture, pre, progress, section, select, slot, small, source, span, strong, sub, summary, sup, svg, table, tbody, td, template, textarea, tfoot, th, thead, time, tr, u, ul, video.


Flow Control Components

when(condition, thenComponent, elseComponent?)

Reactive conditional rendering. condition can be a boolean, a signal, or any function that returns a boolean. Both branches can be Node, () => Node, or null. Automatically disposes the unmounted branch.

when(
  () => user.loggedIn(),
  () => div({}, 'Welcome back!'),
  () => button({ onClick: () => login() }, 'Login')
)

each(source, itemRenderer, keyFn)

Optimised keyed list rendering. source can be an array or a signal/function returning an array. itemRenderer(item, index) returns a Node (or a function that returns Nodes). keyFn(item, index) returns a unique identifier required for efficient DOM reuse.

const items = $([{ id: 1, text: 'a' }, { id: 2, text: 'b' }])

each(items,
  (item) => Li({}, item.text),
  (item) => item.id
)

When the array changes, elements are added, removed, or reordered with minimal DOM operations.


Batch

batch(fn)

Batch multiple reactive updates into a single flush, improving performance.

batch(() => {
  count(1)
  name('John')
  // effects run only once after the batch ends
})

Mounting mount(component, target)

Clears the target element and mounts the application. Returns the runtime instance (which has a .destroy() method).

mount(() => App(), '#app')
// or
mount(App, document.body)

If you mount again on the same target, the previous instance is automatically destroyed.


Global Cleanup & Memory

SigPro tracks every effect, DOM event listener, and nested component. When a component is unmounted:

  • All its effects are disposed.
  • All DOM event listeners are removed.
  • All onUnmount callbacks run.
  • Child components are recursively destroyed.

You never need to manually clean up just write reactive code.


Full Example Counter with Persistence

import { $, mount } from 'sigpro';

const count = $(0, 'counter') // persists in localStorage

const App = () =>
  div({ class: 'counter' }, [
    h1({}, () => `Count: ${count()}`),
    button({ onClick: () => count(count() + 1) }, '+'),
    button({ onClick: () => count(count() - 1) }, '-'),
    button({ onClick: () => count(0) }, 'Reset')
  ])

mount(App, '#app')