Update Docs
This commit is contained in:
@@ -1,102 +1,142 @@
|
||||
# The Reactive Core: `$( )`
|
||||
|
||||
The `$` function is the heart of **SigPro**. It is a **Unified Reactive Constructor** that handles state, derivations, and automatic persistence through a single, consistent interface.
|
||||
|
||||
## 1. The Constructor: `$( input, [key] )`
|
||||
|
||||
Depending on the arguments you pass, SigPro creates different reactive primitives:
|
||||
|
||||
| Argument | Type | Required | Description |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| **input** | `Value` / `Function` | **Yes** | Initial state or reactive logic. |
|
||||
| **key** | `string` | No | If provided, the signal **persists** in `localStorage`. |
|
||||
The `$` function is a **Unified Reactive Constructor**. It detects the type of input you provide and returns the appropriate reactive primitive.
|
||||
|
||||
---
|
||||
|
||||
## 2. Signal (State & Persistence)
|
||||
## 1. Signals (Atomic State)
|
||||
A **Signal** is the simplest form of reactivity. It holds a single value (string, number, boolean, null).
|
||||
|
||||
A **Signal** is a reactive "box" for data. SigPro now supports **Native Persistence**: if you provide a second argument (the `key`), the signal will automatically sync with `localStorage`.
|
||||
|
||||
* **Standard:** `const $count = $(0);`
|
||||
* **Persistent:** `const $theme = $("light", "app-theme");` (Restores value on page reload).
|
||||
|
||||
### Example:
|
||||
### **Option A: Standard Signal (RAM)**
|
||||
Ideal for volatile state that shouldn't persist after a page refresh.
|
||||
```javascript
|
||||
const $user = $("Guest", "session-user"); // Automatically saved/loaded
|
||||
const $count = $(0);
|
||||
|
||||
// Read (Getter)
|
||||
console.log($user());
|
||||
// Usage:
|
||||
$count(); // Getter: returns 0
|
||||
$count(10); // Setter: updates to 10
|
||||
$count(c => c + 1); // Functional update: updates to 11
|
||||
```
|
||||
|
||||
// Update (Setter + Auto-save to Disk)
|
||||
$user("Alice");
|
||||
### **Option B: Persistent Signal (Disk)**
|
||||
By adding a `key`, SigPro links the signal to `localStorage`.
|
||||
```javascript
|
||||
// Syntax: $(initialValue, "storage-key")
|
||||
const $theme = $("light", "app-theme");
|
||||
|
||||
// Functional Update
|
||||
$user(prev => prev.toUpperCase());
|
||||
// It restores the value from disk automatically on load.
|
||||
// When you update it, it saves to disk instantly:
|
||||
$theme("dark"); // localStorage.getItem("app-theme") is now "dark"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Computed (Derived State)
|
||||
## 2. Stores (Reactive Objects)
|
||||
A **Store** is a proxy that wraps an **Object**. SigPro makes every property reactive recursively. You access and set properties as if they were individual signals.
|
||||
|
||||
When you pass a **function** that **returns a value**, SigPro creates a **Computed Signal**. It tracks dependencies and recalculates only when necessary.
|
||||
### **Option A: Standard Store (RAM)**
|
||||
```javascript
|
||||
const user = $({
|
||||
name: "Alice",
|
||||
profile: { bio: "Developer" }
|
||||
});
|
||||
|
||||
* **Syntax:** `const $derived = $(() => logic);`
|
||||
// Getter: Call the property as a function
|
||||
console.log(user.name()); // "Alice"
|
||||
|
||||
// Setter: Pass the value to the property function
|
||||
user.name("Bob");
|
||||
|
||||
// Nested updates work exactly the same:
|
||||
user.profile.bio("Architect");
|
||||
```
|
||||
|
||||
### **Option B: Persistent Store (Disk)**
|
||||
The most powerful way to save complex state. The **entire object tree** is serialized to JSON and kept in sync with the disk.
|
||||
```javascript
|
||||
const settings = $({
|
||||
volume: 50,
|
||||
notifications: true
|
||||
}, "user-settings");
|
||||
|
||||
// Any change in the object triggers a disk sync:
|
||||
settings.volume(100); // The whole JSON is updated in localStorage
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Stores (Reactive Arrays)
|
||||
When you pass an **Array**, SigPro tracks changes to the list. You can use standard methods or access indexes as reactive getters.
|
||||
|
||||
```javascript
|
||||
const $list = $(["Item 1", "Item 2"]);
|
||||
|
||||
// Get by index
|
||||
console.log($list[0]()); // "Item 1"
|
||||
|
||||
// Update by index
|
||||
$list[0]("Updated Item");
|
||||
|
||||
// Note: For adding/removing items, use standard array methods
|
||||
// which SigPro makes reactive (push, pop, splice, etc.)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Computed (Derived Logic)
|
||||
A **Computed Signal** is a read-only value that depends on other signals. It is defined by passing a **function that returns a value**.
|
||||
|
||||
### Example:
|
||||
```javascript
|
||||
const $price = $(100);
|
||||
const $qty = $(2);
|
||||
const $tax = $(0.21);
|
||||
|
||||
// Auto-tracks $price and $qty
|
||||
const $total = $(() => $price() * $qty());
|
||||
|
||||
$qty(3); // $total updates to 300 automatically
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Effects (Reactive Actions)
|
||||
|
||||
An **Effect** is a function that **does not return a value**. It performs an action (side effect) whenever the signals it "touches" change.
|
||||
|
||||
* **When to use:** Logging, manual DOM tweaks, or syncing with external APIs.
|
||||
* **Syntax:** `$(() => { action });`
|
||||
|
||||
### Example:
|
||||
```javascript
|
||||
const $status = $("online");
|
||||
|
||||
// Runs every time $status changes
|
||||
$(() => {
|
||||
console.log("System status is now:", $status());
|
||||
// This function HAS a return statement
|
||||
const $total = $(() => {
|
||||
return $price() * (1 + $tax());
|
||||
});
|
||||
|
||||
// Usage (Read-only):
|
||||
console.log($total()); // 121
|
||||
|
||||
$price(200);
|
||||
console.log($total()); // 242 (Auto-updated)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Summary Table: Usage Guide
|
||||
|
||||
| Primitive | Logic Type | Persistence? | Typical Use Case |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| **Signal** | Mutable State | **Yes** (Optional) | `$(0, 'counter')` |
|
||||
| **Computed** | Derived / Read-only | No | `$(() => $a() + $b())` |
|
||||
| **Effect** | Imperative Action | No | `$(() => alert($msg()))` |
|
||||
|
||||
---
|
||||
|
||||
## 💡 Pro Tip: The Power of Native Persistence
|
||||
|
||||
In SigPro, you don't need external plugins for basic storage. By using the `key` parameter in a Signal, you gain:
|
||||
1. **Zero Boilerplate:** No more `JSON.parse(localStorage.getItem(...))`.
|
||||
2. **Instant Hydration:** The value is restored **before** the UI renders, preventing "flicker".
|
||||
3. **Atomic Safety:** Data is saved to disk exactly when the signal changes, ensuring your app state is always safe.
|
||||
|
||||
---
|
||||
|
||||
### Naming Convention
|
||||
We use the **`$` prefix** (e.g., `$count`) for reactive functions to distinguish them from static variables at a glance:
|
||||
## 5. Effects (Reactive Actions)
|
||||
An **Effect** is used for side-effects. It is defined by passing a **function that does NOT return a value**. It runs once immediately and then re-runs whenever its dependencies change.
|
||||
|
||||
```javascript
|
||||
let count = 0; // Static
|
||||
const $count = $(0); // Reactive Signal
|
||||
const $name = $("Alice");
|
||||
|
||||
// This function has NO return statement (Side-effect)
|
||||
$(() => {
|
||||
console.log("The name changed to:", $name());
|
||||
document.title = `Profile: ${$name()}`;
|
||||
});
|
||||
|
||||
$name("Bob"); // Triggers the console.log and updates document.title
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Summary: Input Mapping
|
||||
|
||||
| If you pass... | SigPro creates a... | Access Method |
|
||||
| :--- | :--- | :--- |
|
||||
| **A Value** | **Signal** | `$var()` / `$var(val)` |
|
||||
| **An Object** | **Store** | `obj.prop()` / `obj.prop(val)` |
|
||||
| **An Array** | **Array Store** | `arr[i]()` / `arr.push()` |
|
||||
| **Function (returns)** | **Computed** | `$comp()` (Read-only) |
|
||||
| **Function (no return)** | **Effect** | Automatically executed |
|
||||
|
||||
---
|
||||
|
||||
## 💡 Naming Convention: The `$` Prefix
|
||||
To keep your code clean, always prefix your reactive variables with `$`. This tells you at a glance that you need to call it as a function to get its value.
|
||||
|
||||
```javascript
|
||||
const name = "Static"; // Just a string
|
||||
const $name = $("Alice"); // A Reactive Signal
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user