# ⚡ SigPro – Complete API Reference SigPro is a **Real‑DOM first** reactive micro‑framework. No virtual DOM, no diffing overhead – it updates the DOM directly with surgical precision. Built‑in automatic cleanup prevents memory leaks, and the API is designed to be both tiny and powerful. ```javascript import { $, $$, watch, h, when, each, fx, router, req, mount, batch } from 'sigpro' // Or, if you prefer the global style in an ESM environment: // import { sigpro } from 'sigpro'; sigpro(); // then $, h, div... become window globals // In a classic IIFE script (` - Or in ESM, call `sigpro()` after importing: `import { sigpro } from 'sigpro'; sigpro();` After that, you can write `div()`, `span()`, etc. directly, without any import. 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 }) ``` --- ## ✨ Animations – `fx(options, child)` Applies smooth enter animations (CSS transitions / keyframes). Returns the modified element. ```javascript fx({ name: 'fade', duration: 300 }, div({}, 'Hello') ) ``` **Options** - `name` – uses predefined keyframes `${name}-in` (you must define them in your CSS) - `duration` – in ms (default 200) - `scale` – adds `scale(0.95)` → `none` - `slide` – adds `translateY(-10px)` → `none` - `rotate` – adds `rotate(-2deg)` → `none` - `blur` – adds `blur(4px)` → `none` If `name` is given, it sets `animation: ${name}-in ${duration}ms`. Otherwise it applies a smooth transition from the initial transform/filter to the final state. --- ## 🧭 Router – `router(routes)` Hash‑based SPA router. Returns a DOM node that renders the current route. ```javascript const routes = [ { path: '/', component: () => div({}, 'Home') }, { path: '/user/:id', component: (params) => div({}, `User ${params.id}`) }, { path: '*', component: () => div({}, '404') } ] const App = () => div({}, [ a({ href: '#/' }, 'Home'), a({ href: '#/user/42' }, 'User 42'), router(routes) ]) ``` **API** | Method | Description | |--------|-------------| | `router.params()` | Returns a reactive signal of current route params (e.g., `{ id: '42' }`). | | `router.to(path)` | Navigate to a new hash (e.g., `router.to('/user/5')`). Prepend `#` automatically. | | `router.back()` | Go back in history. | | `router.path()` | Returns current hash path without `#` (e.g., `/user/42`). | --- ## 🌐 HTTP Requests – `req(config)` Creates a reactive request controller with built‑in loading/error/data signals and abort support. ```javascript const fetchUser = req({ url: '/api/user/1', method: 'GET' }) // start the request fetchUser.run().catch(console.error) // reactively display state watch(() => { if (fetchUser.loading()) console.log('loading...') if (fetchUser.error()) console.error(fetchUser.error()) if (fetchUser.data()) console.log(fetchUser.data()) }) // abort if needed fetchUser.abort() ``` **Options** - `url` (required) - `method` (default `'GET'`) - `headers` (object, default `{}`) **Return value** - `run(body?)` – initiates the request, returns a promise. - `abort()` – aborts the current request (AbortController). - `loading` – signal (boolean) - `error` – signal (`null` or error message) - `data` – signal (`null` or parsed JSON) > **Note**: Automatically sets `Content-Type: application/json` unless `body` is a `FormData`. Timeout after 10 seconds aborts the request. --- ## 🚀 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 { $, watch, h, 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') ``` --- ## 🔧 Customising the API (Renaming) You can rename everything in one line: ```javascript import { $ as signal, watch as effect, h as element, mount as render } from 'sigpro' ``` Or assign globally (after calling `sigpro()` or using the classic script): ```javascript window.myReactive = $ ```