Quick API Reference ⚡
A comprehensive reference for all SigPro APIs. Everything you need to build reactive web applications with signals and web components.
📋 API Functions Reference
| Function | Description | Example |
|---|---|---|
$(initialValue) | Creates a reactive signal (getter/setter) | const count = $(0) |
$(computedFn) | Creates a computed signal | const full = $(() => first() + last()) |
$.effect(fn) | Runs effect when dependencies change | $.effect(() => console.log(count())) |
$.page(setupFn) | Creates a page with automatic cleanup | $.page(() => htmlPage ) |
$.component(tagName, setupFn, attrs, useShadow) | Creates reactive Web Component | $.component('my-menu', setup, ['items']) |
$.router(routes) | Creates a hash-based router | $.router([{path:'/', component:Home}]) |
$.router.go(path) | Navigates to a route | $.router.go('/user/42') |
$.fetch(url, data, loadingSignal) | Fetch wrapper with loading state | const data = await $.fetch('/api', data, loading) |
$.storage(key, initialValue, storageType) | Persistent signal (local/sessionStorage) | const theme = $.storage('theme', 'light') |
html`...` | Template literal for reactive HTML | html`<div>${count}</div>` |
Signal Methods
| Method | Description | Example |
|---|---|---|
signal() | Gets current value | count() |
signal(newValue) | Sets new value | count(5) |
signal(prev => new) | Updates using previous value | count(c => c + 1) |
Component Context Properties
| Property | Description | Example |
|---|---|---|
props | Reactive component properties | props.title() |
slot(name) | Accesses slot content | slot() or slot('footer') |
emit(event, data) | Dispatches custom event | emit('update', value) |
onUnmount(cb) | Registers cleanup callback | onUnmount(() => clearInterval(timer)) |
Page Context Properties
| Property | Description | Example |
|---|---|---|
params | Route parameters | params.id, params.slug |
onUnmount(cb) | Registers cleanup callback | onUnmount(() => clearInterval(timer)) |
HTML Directives
| Directive | Description | Example |
|---|---|---|
@event | Event listener | @click=${handler} |
:property | Two-way binding | :value=${signal} |
?attribute | Boolean attribute | ?disabled=${signal} |
.property | DOM property binding | .scrollTop=${value} |
class:name | Conditional class | class:active=${isActive} |
📡 Signals - $(initialValue)
Creates a reactive value that notifies dependents when changed.
| Pattern | Example | Description |
|---|---|---|
| Basic Signal | const count = $(0) | Create signal with initial value |
| Getter | count() | Read current value |
| Setter | count(5) | Set new value directly |
| Updater | count(prev => prev + 1) | Update based on previous value |
| Computed | const full = $(() => first() + last()) | Auto-updating derived signal |
Examples
javascript
// Basic signal
const count = $(0);
console.log(count()); // 0
count(5);
count(c => c + 1); // 6
// Computed signal
const firstName = $('John');
const lastName = $('Doe');
const fullName = $(() => `${firstName()} ${lastName()}`);
console.log(fullName()); // "John Doe"
firstName('Jane'); // fullName auto-updates to "Jane Doe"🔄 Effects - $.effect(fn)
Executes a function and automatically re-runs when its dependencies change.
| Pattern | Example | Description |
|---|---|---|
| Basic Effect | $.effect(() => console.log(count())) | Run effect on dependency changes |
| Cleanup | $.effect(() => { timer = setInterval(...); return () => clearInterval(timer) }) | Return cleanup function |
| Stop Effect | const stop = $.effect(...); stop() | Manually stop an effect |
Examples
javascript
// Auto-running effect
const count = $(0);
$.effect(() => {
console.log(`Count is: ${count()}`);
}); // Logs immediately and whenever count changes
// Effect with cleanup
const userId = $(1);
$.effect(() => {
const id = userId();
const timer = setInterval(() => fetchUser(id), 5000);
return () => clearInterval(timer); // Cleanup before re-run
});📄 Pages - $.page(setupFunction)
Creates a page with automatic cleanup of all signals and effects when navigated away.
javascript
// pages/about.js
import { $, html } from 'sigpro';
export default $.page(() => {
const count = $(0);
// Auto-cleaned on navigation
$.effect(() => {
document.title = `Count: ${count()}`;
});
return html`
<div>
<h1>About Page</h1>
<p>Count: ${count}</p>
<button @click=${() => count(c => c + 1)}>+</button>
</div>
`;
});With Parameters
javascript
export default $.page(({ params, onUnmount }) => {
const userId = params.id;
// Manual cleanup if needed
const interval = setInterval(() => refresh(), 10000);
onUnmount(() => clearInterval(interval));
return html`<div>User: ${userId}</div>`;
});🧩 Components - $.component(tagName, setup, observedAttributes, useShadowDOM)
Creates Custom Elements with reactive properties.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
tagName | string | required | Custom element tag (must include hyphen) |
setupFunction | Function | required | Function that renders the component |
observedAttributes | string[] | [] | Attributes to observe for changes |
useShadowDOM | boolean | false | true = Shadow DOM (encapsulated), false = Light DOM |
Light DOM Example (Default)
javascript
// button.js - inherits global styles
$.component('my-button', (props, { slot, emit }) => {
return html`
<button
class="px-4 py-2 bg-blue-500 text-white rounded"
@click=${() => emit('click')}
>
${slot()}
</button>
`;
}, ['variant']); // Observe 'variant' attributeShadow DOM Example
javascript
// calendar.js - encapsulated styles
$.component('my-calendar', (props) => {
return html`
<style>
/* These styles are isolated */
.calendar {
background: white;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
</style>
<div class="calendar">
${renderCalendar(props.date())}
</div>
`;
}, ['date'], true); // true = use Shadow DOM🌐 Router - $.router(routes)
Creates a hash-based router with automatic page cleanup.
Route Definition
javascript
const routes = [
// Simple routes
{ path: '/', component: HomePage },
{ path: '/about', component: AboutPage },
// Routes with parameters
{ path: '/user/:id', component: UserPage },
{ path: '/user/:id/posts/:pid', component: PostPage },
// RegExp routes for advanced matching
{ path: /^\/posts\/(?<id>\d+)$/, component: PostPage },
];Usage
javascript
import { $, html } from 'sigpro';
import Home from './pages/Home.js';
import User from './pages/User.js';
const router = $.router([
{ path: '/', component: Home },
{ path: '/user/:id', component: User },
]);
// Navigation
$.router.go('/user/42');
$.router.go('about'); // Same as '/about'
// In templates
html`
<nav>
<a href="#/">Home</a>
<a href="#/user/42">Profile</a>
<button @click=${() => $.router.go('/contact')}>
Contact
</button>
</nav>
`;📦 Storage - $.storage(key, initialValue, [storage])
Persistent signal that syncs with localStorage or sessionStorage.
javascript
// localStorage (default)
const theme = $.storage('theme', 'light');
const user = $.storage('user', null);
const settings = $.storage('settings', { notifications: true });
// sessionStorage
const tempData = $.storage('temp', {}, sessionStorage);
// Usage like a normal signal
theme('dark'); // Auto-saves to localStorage
console.log(theme()); // 'dark' (even after page refresh)🌐 Fetch - $.fetch(url, data, [loading])
Simple fetch wrapper with automatic JSON handling.
javascript
const loading = $(false);
async function loadUser(id) {
const user = await $.fetch(`/api/users/${id}`, null, loading);
if (user) userData(user);
}
// In template
html`
<div>
${() => loading() ? html`<spinner></spinner>` : html`
<p>${userData()?.name}</p>
`}
</div>
`;🎨 Template Literals - html`...`
Creates reactive DOM fragments with directives.
Directives Reference
| Directive | Example | Description |
|---|---|---|
| Event | @click=${handler} | Add event listener |
| Two-way binding | :value=${signal} | Bind signal to input value |
| Boolean attribute | ?disabled=${signal} | Toggle boolean attribute |
| Property | .scrollTop=${value} | Set DOM property directly |
| Class toggle | class:active=${isActive} | Toggle class conditionally |
Examples
javascript
const text = $('');
const isDisabled = $(false);
const activeTab = $('home');
html`
<!-- Event binding -->
<button @click=${() => count(c => c + 1)}>+</button>
<!-- Two-way binding -->
<input :value=${text} />
<p>You typed: ${text}</p>
<!-- Boolean attributes -->
<button ?disabled=${isDisabled}>Submit</button>
<!-- Class toggles -->
<div class:active=${activeTab() === 'home'}>
Home content
</div>
<!-- Property binding -->
<div .scrollTop=${scrollPosition}></div>
`;🎯 Complete Component Example
javascript
import { $, html } from 'sigpro';
// Create a component
$.component('user-profile', (props, { slot, emit }) => {
// Reactive state
const user = $(null);
const loading = $(false);
// Load user data when userId changes
$.effect(() => {
const id = props.userId();
if (id) {
loading(true);
$.fetch(`/api/users/${id}`, null, loading)
.then(data => user(data));
}
});
// Computed value
const fullName = $(() =>
user() ? `${user().firstName} ${user().lastName}` : ''
);
// Template
return html`
<div class="user-profile">
${() => loading() ? html`
<div class="spinner">Loading...</div>
` : user() ? html`
<h2>${fullName}</h2>
<p>Email: ${user().email}</p>
<button @click=${() => emit('select', user())}>
${slot('Select')}
</button>
` : html`
<p>User not found</p>
`}
</div>
`;
}, ['user-id']); // Observe userId attribute