5.7 KiB
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:
-
Auto‑track mode – pass a function:
watch(() => { /* reads signals */ })
Automatically re‑runs whenever any signal read inside changes. -
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 depth‑aware – 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' |
| Two‑way 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 re‑executed 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, h1…h6, 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
onUnmountcallbacks 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')