Files
sigpro/docs/api/global.md
natxocc d46c5ca3af
All checks were successful
Deploy Docs to Synology / deploy (push) Successful in 4s
update Docs
2026-04-28 19:05:23 +02:00

5.6 KiB
Raw Blame History

Global State Management: Atomic & Modular

SigPro leverages the native power and efficiency of signals to create robust global stores with zero complexity. While other frameworks force you into heavy libraries and rigid boilerplate (Redux, Pinia, or Svelte stores), SigPro treats “the store” as a simple architectural choice: defining a signal outside of a component.

Availability: $ (and other core functions) are exported from the SigPro module. In ESM you must import them (import { $ } from 'sigpro'). In the IIFE classic script, $ is automatically available on window. The examples below assume $ is already in scope (via import or global).

Modular Organization (Zero Constraints)

You are not restricted to a single store.js. You can organize your state by feature, domain, or page. Since a SigPro store is just a standard JavaScript module exporting signals, you can name your files whatever you like (auth.js, cart.js, settings.js) to keep your logic clean.

1. FileBased Stores (<any-name>.js)

Creating a dedicated file allows you to export only what you need. This modularity ensures tree shaking works perfectly you never load state that isnt imported.

// auth.js
import { $ } from 'sigpro';

// A simple global signal
export const user = $({ name: "Guest", loggedIn: false });

// A persistent global signal (autosyncs with localStorage)
export const theme = $("light", "app-theme-pref");

// A computed global signal that reacts to the 'user' signal
export const welcomeMessage = $(() => `Welcome back, ${user().name}!`);

2. CrossComponent Consumption

Once exported, these signals act as a single source of truth. SigPro ensures that if a signal changes in one file, every component importing it across the entire app updates atomically without a full rerender.

// Profile.js
import { user } from "./auth.js";

const Profile = () => div([
  h2(() => user().name),
  button({ onclick: () => user({ name: "John Doe", loggedIn: true }) }, "Log In")
]);

// Navbar.js
import { welcomeMessage, theme } from "./auth.js";

const Navbar = () => nav({ class: () => theme() }, [
  span(() => welcomeMessage())
]);

Why SigPro Stores Are Superior

Feature SigPro Redux / Pinia / Svelte
Boilerplate 0% (just a variable) High (actions, reducers, stores)
Organization Unlimited (any filename) Often strictly “store” files
Persistence Native (just add a key) Requires middleware / plugins
Learning Curve Instant Steep / complex
Bundle Size 0KB (part of core) 10KB 30KB+

The Persistence Advantage

The magic of SigPros $(value, "key") is that it works identically for local and global states. By simply adding a second argument, your modular store survives browser refreshes automatically. No manual localStorage.getItem or JSON.parse logic is ever required.

// This single line creates a global, reactive,
// and persistent store for a shopping cart.
export const cart = $([], "session-cart");

Summary of Scopes

Scope Definition Behaviour
Local Signal defined inside a component Unique to every component instance
Module Signal defined outside a component (same file) Shared by all instances within that file
Global Signal defined in a separate file and imported Shared across the entire application
Persistent Any Signal defined with a key (e.g., $([], "cart")) Shared globally and persisted in localStorage

Complete Example Todo Store

// store/todos.js
import { $ } from 'sigpro';

export const todos = $([], "todos");
export const filter = $("all");

export const addTodo = (text) => {
  todos([...todos(), { id: Date.now(), text, done: false }]);
};

export const toggleTodo = (id) => {
  todos(todos().map(t => t.id === id ? { ...t, done: !t.done } : t));
};

export const filteredTodos = $(() => {
  const all = todos();
  if (filter() === "active") return all.filter(t => !t.done);
  if (filter() === "completed") return all.filter(t => t.done);
  return all;
});
// components/TodoApp.js
import 'sigpro';
import { todos, filter, addTodo, toggleTodo, filteredTodos } from "../store/todos.js";

const TodoApp = () =>
  div({ class: "todo-app" }, [
    input({ placeholder: "Add todo...", onKeyDown: (e) => {
      if (e.key === "Enter" && e.target.value) {
        addTodo(e.target.value);
        e.target.value = "";
      }
    }}),
    div({ class: "filters" }, [
      button({ onClick: () => filter("all") }, "All"),
      button({ onClick: () => filter("active") }, "Active"),
      button({ onClick: () => filter("completed") }, "Completed")
    ]),
    ul(
      each(filteredTodos,
        (todo) => li([
          input({ type: "checkbox", checked: () => todo.done, onInput: () => toggleTodo(todo.id) }),
          span(() => todo.done ? s(todo.text) : todo.text)
        ]),
        (todo) => todo.id
      )
    )
  ]);

mount(TodoApp, "#app");