# Quick API Reference ⚡ | SigPro
Minimalist Reactive Library

Skip to content

# 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(() => html` Page `)`
`$.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' attribute

### Shadow 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