# 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** ```javascript 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. **Auto‑track mode** – pass a function: `watch(() => { /* reads signals */ })` Automatically re‑runs 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. ```javascript // 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: ```javascript 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. ```javascript 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. ```javascript 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. ```javascript 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). ```javascript 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 ```javascript 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') ```