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

142 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.
```javascript
// 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.
```javascript
// 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.
```javascript
// 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
```javascript
// 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;
});
```
```javascript
// 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");
```