From 617a5d32c6f33ae76e1dcc0830c3f89d36bb111f Mon Sep 17 00:00:00 2001 From: natxocc Date: Thu, 26 Mar 2026 14:59:31 +0100 Subject: [PATCH] Include if for in Docs --- docs/404.html | 2 +- docs/api/for.html | 44 ++++++++++ docs/api/html.html | 6 +- docs/api/if.html | 44 ++++++++++ docs/api/mount.html | 6 +- docs/api/quick.html | 6 +- docs/api/router.html | 6 +- docs/api/signal.html | 4 +- docs/api/tags.html | 6 +- docs/api/watch.html | 6 +- docs/assets/api_for.md.CGMDz0Px.js | 19 ++++ docs/assets/api_for.md.CGMDz0Px.lean.js | 1 + docs/assets/api_if.md.C-36XjK0.js | 19 ++++ docs/assets/api_if.md.C-36XjK0.lean.js | 1 + ...d.Dw-DUc7L.js => api_quick.md.D3C2EJww.js} | 2 +- ....lean.js => api_quick.md.D3C2EJww.lean.js} | 0 ....md.HK-a2_Fb.js => install.md.C1tyiPaQ.js} | 4 +- ...Fb.lean.js => install.md.C1tyiPaQ.lean.js} | 0 docs/hashmap.json | 2 +- docs/index.html | 2 +- docs/install.html | 8 +- docs/ui/quick.html | 4 +- docs/vite/plugin.html | 4 +- src/docs/.vitepress/config.js | 4 +- src/docs/api/for.md | 83 +++++++++++++++++ src/docs/api/if.md | 88 +++++++++++++++++++ src/docs/api/quick.md | 4 +- 27 files changed, 338 insertions(+), 37 deletions(-) create mode 100644 docs/api/for.html create mode 100644 docs/api/if.html create mode 100644 docs/assets/api_for.md.CGMDz0Px.js create mode 100644 docs/assets/api_for.md.CGMDz0Px.lean.js create mode 100644 docs/assets/api_if.md.C-36XjK0.js create mode 100644 docs/assets/api_if.md.C-36XjK0.lean.js rename docs/assets/{api_quick.md.Dw-DUc7L.js => api_quick.md.D3C2EJww.js} (97%) rename docs/assets/{api_quick.md.Dw-DUc7L.lean.js => api_quick.md.D3C2EJww.lean.js} (100%) rename docs/assets/{install.md.HK-a2_Fb.js => install.md.C1tyiPaQ.js} (96%) rename docs/assets/{install.md.HK-a2_Fb.lean.js => install.md.C1tyiPaQ.lean.js} (100%) create mode 100644 src/docs/api/for.md create mode 100644 src/docs/api/if.md diff --git a/docs/404.html b/docs/404.html index c53e0a9..fbc591c 100644 --- a/docs/404.html +++ b/docs/404.html @@ -17,7 +17,7 @@
- + \ No newline at end of file diff --git a/docs/api/for.html b/docs/api/for.html new file mode 100644 index 0000000..c1facbc --- /dev/null +++ b/docs/api/for.html @@ -0,0 +1,44 @@ + + + + + + ♻️ Reactive Lists: $.for( ) | SigPro + + + + + + + + + + + + + + + +
Skip to content

♻️ Reactive Lists: $.for( )

The $.for function is a high-performance list renderer. It maps an array (or a Signal containing an array) to DOM nodes. Unlike a simple .map(), $.for is keyed, meaning it only updates, moves, or deletes the specific items that changed.

🛠️ Function Signature

typescript
$.for(
+  source: Signal<any[]> | Function | any[], 
+  render: (item: any, index: number) => HTMLElement, 
+  keyFn: (item: any, index: number) => string | number
+): HTMLElement
ParameterTypeRequiredDescription
sourceSignalYesThe reactive array to iterate over.
renderFunctionYesA function that returns a component or Node for each item.
keyFnFunctionYesA function to extract a unique ID for each item (crucial for performance).

Returns: A div element with display: contents containing the live list.


📖 Usage Patterns

1. Basic Keyed List

Always use a unique property (like an id) as a key to ensure SigPro doesn't recreate nodes unnecessarily.

javascript
const users = $([
+  { id: 1, name: "Alice" },
+  { id: 2, name: "Bob" }
+]);
+
+Ul({ class: "list" }, [
+  $.for(users, 
+    (user) => Li({ class: "p-2" }, user.name),
+    (user) => user.id
+  )
+]);

2. Handling Primitive Arrays

If your array contains simple strings or numbers, you can use the value itself or the index as a key (though the index is less efficient for reordering).

javascript
const tags = $(["Tech", "JS", "Web"]);
+
+Div({ class: "flex gap-1" }, [
+  $.for(tags, (tag) => Badge(tag), (tag) => tag)
+]);

🏗️ How it Works (The Reconciliation)

When the source signal changes, $.for performs the following steps:

  1. Key Diffing: It compares the new keys with the previous ones stored in an internal Map.
  2. Node Reuse: If a key already exists, the DOM node is reused and moved to its new position. No new elements are created.
  3. Cleanup: If a key disappears from the list, SigPro calls .destroy() on that specific item's instance. This stops all its internal watchers and removes its DOM nodes.

💡 Performance Tips

  • Stable Keys: Never use Math.random() as a key. This will force SigPro to destroy and recreate the entire list on every update, killing performance.
  • Component Encapsulation: If each item in your list has its own complex internal state, $.for ensures that state is preserved even if the list is reordered, as long as the key remains the same.

🧪 Summary Comparison

FeatureStandard Array.mapSigPro $.for
Re-renderRe-renders everythingOnly updates changes
DOM NodesRe-created every timeReused via Keys
MemoryPotential leaksAutomatic Cleanup
StateLost on re-renderPreserved per item
+ + + + \ No newline at end of file diff --git a/docs/api/html.html b/docs/api/html.html index 764423a..afae41c 100644 --- a/docs/api/html.html +++ b/docs/api/html.html @@ -19,7 +19,7 @@ -
Skip to content

🏗️ The DOM Factory: $.html( )

$.html is the internal engine that creates, attributes, and attaches reactivity to DOM elements. It uses $.watch to maintain a live, high-performance link between your Signals and the Document Object Model.

🛠 Function Signature

typescript
$.html(tagName: string, props?: Object, children?: any[] | any): HTMLElement
ParameterTypeRequiredDescription
tagNamestringYesValid HTML tag name (e.g., "div", "button").
propsObjectNoHTML attributes, event listeners, and reactive bindings.
childrenanyNoNested elements, text strings, or reactive functions.

📖 Key Features

1. Attribute Handling

SigPro intelligently decides how to apply each property:

  • Standard Props: Applied via setAttribute or direct property assignment.
  • Boolean Props: Uses toggleAttribute (e.g., checked, disabled, hidden).
  • Class Names: Supports class or className interchangeably.

2. Event Listeners & Modifiers

Events are defined by the on prefix. SigPro supports Dot Notation for common event operations:

javascript
$.html("button", {
+    
Skip to content

🏗️ The DOM Factory: $.html( )

$.html is the internal engine that creates, attributes, and attaches reactivity to DOM elements. It uses $.watch to maintain a live, high-performance link between your Signals and the Document Object Model.

🛠 Function Signature

typescript
$.html(tagName: string, props?: Object, children?: any[] | any): HTMLElement
ParameterTypeRequiredDescription
tagNamestringYesValid HTML tag name (e.g., "div", "button").
propsObjectNoHTML attributes, event listeners, and reactive bindings.
childrenanyNoNested elements, text strings, or reactive functions.

📖 Key Features

1. Attribute Handling

SigPro intelligently decides how to apply each property:

  • Standard Props: Applied via setAttribute or direct property assignment.
  • Boolean Props: Uses toggleAttribute (e.g., checked, disabled, hidden).
  • Class Names: Supports class or className interchangeably.

2. Event Listeners & Modifiers

Events are defined by the on prefix. SigPro supports Dot Notation for common event operations:

javascript
$.html("button", {
   // e.preventDefault() is called automatically
   "onsubmit.prevent": (e) => save(e), 
   
@@ -42,8 +42,8 @@
 Div({ class: "wrapper" }, [ Span("Hello") ])
 
 // Is exactly equivalent to:
-$.html("div", { class: "wrapper" }, [ $.html("span", {}, "Hello") ])
- +$.html("div", { class: "wrapper" }, [ $.html("span", {}, "Hello") ])
+ \ No newline at end of file diff --git a/docs/api/if.html b/docs/api/if.html new file mode 100644 index 0000000..6503b06 --- /dev/null +++ b/docs/api/if.html @@ -0,0 +1,44 @@ + + + + + + 🔀 Reactive Branching: $.if( ) | SigPro + + + + + + + + + + + + + + + +
Skip to content

🔀 Reactive Branching: $.if( )

The $.if function is a reactive control flow operator. It manages the conditional rendering of components, ensuring that only the active branch exists in the DOM and in memory.

🛠️ Function Signature

typescript
$.if(
+  condition: Signal<boolean> | Function, 
+  thenVal: Component | Node, 
+  otherwiseVal?: Component | Node
+): HTMLElement
ParameterTypeRequiredDescription
conditionSignalYesA reactive source that determines which branch to render.
thenValanyYesThe content to show when the condition is truthy.
otherwiseValanyNoThe content to show when the condition is falsy (defaults to null).

Returns: A div element with display: contents that acts as a reactive portal for the branches.


📖 Usage Patterns

1. Simple Toggle

The most common use case is showing or hiding a single element based on a state.

javascript
const isVisible = $(false);
+
+Div([
+  Button({ onclick: () => isVisible(!isVisible()) }, "Toggle Message"),
+  
+  $.if(isVisible, 
+    P("Now you see me!"), 
+    P("Now you don't...")
+  )
+]);

2. Lazy Component Loading

Unlike using a hidden class (CSS display: none), $.if is lazy. The branch that isn't active is never created. This saves memory and initial processing time.

javascript
$.if(() => user.isLogged(), 
+  () => Dashboard(), // Only executed if logged in
+  () => LoginGate()  // Only executed if guest
+)

🧹 Automatic Cleanup

One of the core strengths of $.if is its integrated Cleanup logic. SigPro ensures that when a branch is swapped out, it is completely purged.

  1. Stop Watchers: All $.watch calls inside the inactive branch are permanently stopped.
  2. Unbind Events: Event listeners attached via $.html are removed.
  3. Recursive Sweep: SigPro performs a deep "sweep" of the removed branch to ensure no nested reactive effects remain active.

💡 Best Practices

  • Function Wrappers: If your branches are heavy (e.g., they contain complex components), wrap them in a function () => MyComponent(). This prevents the component from being initialized until the condition actually meets its requirement.
  • Logical Expressions: You can pass a complex computed function as the condition:
    javascript
    $.if(() => count() > 10 && status() === 'ready', 
    +  Span("Threshold reached!")
    +)

🏗️ Technical Comparison

FeatureStandard CSS hiddenSigPro $.if
DOM PresenceAlways presentOnly if active
ReactivityStill processing in backgroundPaused/Destroyed
Memory usageHigherOptimized
CleanupManualAutomatic
+ + + + \ No newline at end of file diff --git a/docs/api/mount.html b/docs/api/mount.html index 6e20bb0..a535543 100644 --- a/docs/api/mount.html +++ b/docs/api/mount.html @@ -19,7 +19,7 @@ -
Skip to content

🔌 Application Mounter: $.mount( )

The $.mount function is the entry point of your reactive world. It bridges the gap between your SigPro logic and the browser's Real DOM by injecting a component into the document and initializing its reactive lifecycle.

🛠️ Function Signature

typescript
$.mount(node: Function | HTMLElement, target?: string | HTMLElement): RuntimeObject
ParameterTypeDefaultDescription
nodeFunction or NodeRequiredThe component function or DOM element to render.
targetstring or Nodedocument.bodyCSS selector or DOM element where the app will live.

Returns: A Runtime object containing the container and a destroy() method to wipe all reactivity and DOM nodes.


📖 Common Usage Scenarios

1. The SPA Entry Point

In a Single Page Application, you typically mount your main component to the body or a root div. SigPro manages the entire view from that point.

javascript
import { $ } from './sigpro.js';
+    
Skip to content

🔌 Application Mounter: $.mount( )

The $.mount function is the entry point of your reactive world. It bridges the gap between your SigPro logic and the browser's Real DOM by injecting a component into the document and initializing its reactive lifecycle.

🛠️ Function Signature

typescript
$.mount(node: Function | HTMLElement, target?: string | HTMLElement): RuntimeObject
ParameterTypeDefaultDescription
nodeFunction or NodeRequiredThe component function or DOM element to render.
targetstring or Nodedocument.bodyCSS selector or DOM element where the app will live.

Returns: A Runtime object containing the container and a destroy() method to wipe all reactivity and DOM nodes.


📖 Common Usage Scenarios

1. The SPA Entry Point

In a Single Page Application, you typically mount your main component to the body or a root div. SigPro manages the entire view from that point.

javascript
import { $ } from './sigpro.js';
 import App from './App.js';
 
 // Mounts your main App component
@@ -34,8 +34,8 @@
 $.mount(Counter, '#sidebar-widget');

🔄 How it Works (Lifecycle & Cleanup)

When $.mount is executed, it performs these critical steps to ensure a leak-free environment:

  1. Duplicate Detection: If you call $.mount on a target that already has a SigPro instance, it automatically calls .destroy() on the previous instance. This prevents "Zombie Effects" from stacking in memory.
  2. Internal Scoping: It executes the component function inside an internal Reactive Owner. This captures every $.watch and event listener created during the render.
  3. Target Injection: It clears the target using replaceChildren() and appends the new component.
  4. Runtime Creation: It returns a control object:
    • container: The actual DOM element created.
    • destroy(): The "kill switch" that runs all cleanups, stops all watchers, and removes the element from the DOM.

🛑 Manual Unmounting

While SigPro handles most cleanups automatically (via $.If, $.For, and $.router), you can manually destroy any mounted instance. This is vital for imperatively managed UI like Toasts or Modals.

javascript
const instance = $.mount(MyToast, '#toast-container');
 
 // Later, to remove the toast and kill its reactivity:
-instance.destroy();

💡 Summary Cheat Sheet

GoalCode Pattern
Mount to body$.mount(App)
Mount to CSS Selector$.mount(App, '#root')
Mount to DOM Node$.mount(App, myElement)
Clean & Re-mountCalling $.mount again on the same target
Total Cleanupconst app = $.mount(App); app.destroy();
- +instance.destroy();

💡 Summary Cheat Sheet

GoalCode Pattern
Mount to body$.mount(App)
Mount to CSS Selector$.mount(App, '#root')
Mount to DOM Node$.mount(App, myElement)
Clean & Re-mountCalling $.mount again on the same target
Total Cleanupconst app = $.mount(App); app.destroy();
+ \ No newline at end of file diff --git a/docs/api/quick.html b/docs/api/quick.html index d765e7b..798d2ee 100644 --- a/docs/api/quick.html +++ b/docs/api/quick.html @@ -13,14 +13,14 @@ - + -
Skip to content

⚡ Quick API Reference

SigPro is a high-performance micro-framework that updates the Real DOM surgically. No Virtual DOM, no unnecessary re-renders, and built-in Cleanup (memory cleanup).

🟢 Core Functions

FunctionSignatureDescription
$(val, key?)(any, string?) => SignalCreates a Signal. If key is provided, it persists in localStorage.
$(fn)(function) => ComputedCreates a Computed Signal that auto-updates when its dependencies change.
$.watch(fn)(function) => stopFnAutomatic Mode: Tracks any signal touched inside. Returns a stop function.
$.watch(deps, fn)(Array, function) => stopFnExplicit Mode: Only runs when signals in deps change. Used for Cleanup.
$.html(tag, props, kids)(string, obj, any) => ElementThe low-level DOM factory. Attaches ._cleanups to every element.
$.If(cond, then, else?)(Signal, fn, fn?) => NodeReactive conditional. Automatically destroys the "else" branch memory.
$.For(list, itemFn)(Signal, fn) => NodeOptimized list renderer. Manages individual item lifecycles.
$.router(routes)(Array) => ElementHash-based SPA router. Uses Explicit Watch to prevent memory leaks.
$.mount(node, target)(any, string|Node) => RuntimeEntry point. Creates a root instance with .destroy() capabilities.

🏗️ Element Constructors (Tags)

SigPro provides PascalCase wrappers for all standard HTML5 tags (e.g., Div, Span, Button).

Syntax Pattern

javascript
Tag({ attributes }, [children])

Attribute & Content Handling

PatternCode ExampleBehavior
Staticclass: "text-red"Standard HTML attribute string.
Reactivedisabled: isLoadingUpdates automatically via internal $.watch.
Two-way$value: usernameBinding Operator: Syncs input $\leftrightarrow$ signal both ways.
TextP({}, () => count())Updates text node surgically without re-rendering the P.
Booleanhidden: isHiddenToggles the attribute based on signal truthiness.
- +
Skip to content

⚡ Quick API Reference

SigPro is a high-performance micro-framework that updates the Real DOM surgically. No Virtual DOM, no unnecessary re-renders, and built-in Cleanup (memory cleanup).

🟢 Core Functions

FunctionSignatureDescription
$(val, key?)(any, string?) => SignalCreates a Signal. If key is provided, it persists in localStorage.
$(fn)(function) => ComputedCreates a Computed Signal that auto-updates when its dependencies change.
$.watch(fn)(function) => stopFnAutomatic Mode: Tracks any signal touched inside. Returns a stop function.
$.watch(deps, fn)(Array, function) => stopFnExplicit Mode: Only runs when signals in deps change. Used for Cleanup.
$.html(tag, props, kids)(string, obj, any) => ElementThe low-level DOM factory. Attaches ._cleanups to every element.
$.if(cond, then, else?)(Signal, fn, fn?) => NodeReactive conditional. Automatically destroys the "else" branch memory.
$.for(list, itemFn)(Signal, fn) => NodeOptimized list renderer. Manages individual item lifecycles.
$.router(routes)(Array) => ElementHash-based SPA router. Uses Explicit Watch to prevent memory leaks.
$.mount(node, target)(any, string|Node) => RuntimeEntry point. Creates a root instance with .destroy() capabilities.

🏗️ Element Constructors (Tags)

SigPro provides PascalCase wrappers for all standard HTML5 tags (e.g., Div, Span, Button).

Syntax Pattern

javascript
Tag({ attributes }, [children])

Attribute & Content Handling

PatternCode ExampleBehavior
Staticclass: "text-red"Standard HTML attribute string.
Reactivedisabled: isLoadingUpdates automatically via internal $.watch.
Two-way$value: usernameBinding Operator: Syncs input $\leftrightarrow$ signal both ways.
TextP({}, () => count())Updates text node surgically without re-rendering the P.
Booleanhidden: isHiddenToggles the attribute based on signal truthiness.
+ \ No newline at end of file diff --git a/docs/api/router.html b/docs/api/router.html index c513a41..0ccbd9a 100644 --- a/docs/api/router.html +++ b/docs/api/router.html @@ -19,7 +19,7 @@ -
Skip to content

🚦 Routing: $.router( ) & $.go( )

SigPro includes a built-in, lightweight Hash Router to create Single Page Applications (SPA). It manages the URL state, matches components to paths, and handles the lifecycle of your pages automatically.

🛠 Router Signature

typescript
$.router(routes: Route[]): HTMLElement

Route Object

PropertyTypeDescription
pathstringThe URL fragment (e.g., "/home", "/user/:id", or "*").
componentFunctionA function that returns a Tag or a $.view.

📖 Usage Patterns

1. Defining Routes

The router returns a div element with the class .router-outlet. When the hash changes, the router destroys the previous view and mounts the new one inside this container.

javascript
const App = () => Div({ class: "app-layout" }, [
+    
Skip to content

🚦 Routing: $.router( ) & $.go( )

SigPro includes a built-in, lightweight Hash Router to create Single Page Applications (SPA). It manages the URL state, matches components to paths, and handles the lifecycle of your pages automatically.

🛠 Router Signature

typescript
$.router(routes: Route[]): HTMLElement

Route Object

PropertyTypeDescription
pathstringThe URL fragment (e.g., "/home", "/user/:id", or "*").
componentFunctionA function that returns a Tag or a $.view.

📖 Usage Patterns

1. Defining Routes

The router returns a div element with the class .router-outlet. When the hash changes, the router destroys the previous view and mounts the new one inside this container.

javascript
const App = () => Div({ class: "app-layout" }, [
   Navbar(),
   // The router outlet is placed here
   $.router([
@@ -40,8 +40,8 @@
   flex: 1;
   padding: 2rem;
   animation: fadeIn 0.2s ease-in;
-}
- +}
+ \ No newline at end of file diff --git a/docs/api/signal.html b/docs/api/signal.html index 71e9da8..49fed55 100644 --- a/docs/api/signal.html +++ b/docs/api/signal.html @@ -19,7 +19,7 @@ -
Skip to content

💎 The Signal Function: $( )

The $( ) function is the core constructor of SigPro. It defines how data is stored, computed, and persisted.

🛠 Function Signature

typescript
$(initialValue: any, key?: string): Signal
+    
Skip to content

💎 The Signal Function: $( )

The $( ) function is the core constructor of SigPro. It defines how data is stored, computed, and persisted.

🛠 Function Signature

typescript
$(initialValue: any, key?: string): Signal
 $(computation: Function): ComputedSignal
ParameterTypeRequiredDescription
initialValueanyYes*The starting value of your signal.
computationFunctionYes*A function that returns a value based on other signals.
keystringNoA unique name to persist the signal in localStorage.

*Either an initial value or a computation function must be provided.


📖 Usage Patterns

1. Simple State

$(value) Creates a writable signal. It returns a function that acts as both getter and setter.

javascript
const count = $(0); 
 
 count();    // Read (0)
@@ -33,7 +33,7 @@
 
 // Adds "C" using the previous state
 list(prev => [...prev, "C"]);
- + \ No newline at end of file diff --git a/docs/api/tags.html b/docs/api/tags.html index 649c798..8a45b6c 100644 --- a/docs/api/tags.html +++ b/docs/api/tags.html @@ -19,7 +19,7 @@ -
Skip to content

🎨 Global Tag Helpers

In SigPro, you don't need to manually type $.html('div', ...) for every element. To keep your code declarative and readable, the engine automatically generates Global Helper Functions for all standard HTML5 tags upon initialization.

1. How it Works

SigPro iterates through a manifest of standard HTML tags and attaches a wrapper function for each one directly to the window object. This creates a specialized DSL (Domain Specific Language) that looks like a template engine but is 100% standard JavaScript.

  • Under the hood: $.html('button', { onclick: ... }, 'Click')
  • SigPro Style: Button({ onclick: ... }, 'Click')

2. The Complete Global Registry

The following functions are injected into the global scope (using PascalCase to prevent naming collisions with common JS variables) and are ready to use:

CategoryAvailable Global Functions
StructureDiv, Span, P, Section, Nav, Main, Header, Footer, Article, Aside
TypographyH1 to H6, Ul, Ol, Li, Dl, Dt, Dd, Strong, Em, Code, Pre, Small, B, U, Mark
InteractiveButton, A, Label, Br, Hr, Details, Summary, Dialog
FormsForm, Input, Select, Option, Textarea, Fieldset, Legend
TablesTable, Thead, Tbody, Tr, Th, Td, Tfoot, Caption
MediaImg, Canvas, Video, Audio, Svg, Iframe, Picture, Source

The SigPro Philosophy: Tags are not "magic strings" handled by a compiler. They are functional constructors. Every time you call Div(), you execute a pure JS function that returns a real, reactive DOM element.


3. Usage Patterns (Smart Arguments)

SigPro tag helpers are flexible. They automatically detect if you are passing attributes, children, or both.

A. Attributes + Children

The standard way to build structured UI.

javascript
Div({ class: 'container', id: 'main' }, [
+    
Skip to content

🎨 Global Tag Helpers

In SigPro, you don't need to manually type $.html('div', ...) for every element. To keep your code declarative and readable, the engine automatically generates Global Helper Functions for all standard HTML5 tags upon initialization.

1. How it Works

SigPro iterates through a manifest of standard HTML tags and attaches a wrapper function for each one directly to the window object. This creates a specialized DSL (Domain Specific Language) that looks like a template engine but is 100% standard JavaScript.

  • Under the hood: $.html('button', { onclick: ... }, 'Click')
  • SigPro Style: Button({ onclick: ... }, 'Click')

2. The Complete Global Registry

The following functions are injected into the global scope (using PascalCase to prevent naming collisions with common JS variables) and are ready to use:

CategoryAvailable Global Functions
StructureDiv, Span, P, Section, Nav, Main, Header, Footer, Article, Aside
TypographyH1 to H6, Ul, Ol, Li, Dl, Dt, Dd, Strong, Em, Code, Pre, Small, B, U, Mark
InteractiveButton, A, Label, Br, Hr, Details, Summary, Dialog
FormsForm, Input, Select, Option, Textarea, Fieldset, Legend
TablesTable, Thead, Tbody, Tr, Th, Td, Tfoot, Caption
MediaImg, Canvas, Video, Audio, Svg, Iframe, Picture, Source

The SigPro Philosophy: Tags are not "magic strings" handled by a compiler. They are functional constructors. Every time you call Div(), you execute a pure JS function that returns a real, reactive DOM element.


3. Usage Patterns (Smart Arguments)

SigPro tag helpers are flexible. They automatically detect if you are passing attributes, children, or both.

A. Attributes + Children

The standard way to build structured UI.

javascript
Div({ class: 'container', id: 'main' }, [
   H1("Welcome to SigPro"),
   P("The zero-VDOM framework.")
 ]);

B. Children Only (The "Skipper")

If you don't need attributes, you can skip the object and pass the content (string, array, or function) directly as the first argument.

javascript
Section([
@@ -54,8 +54,8 @@
       class: () => $online() ? "text-bold" : "text-gray-400" 
     }, name)
   ])
-);
State ($online)Rendered HTMLMemory Management
true<div class="flex..."><span class="w-3..."></span><p class="text-bold">John</p></div>Watcher active
false<div class="flex..."><span hidden class="w-3..."></span><p class="text-gray-400">John</p></div>Attribute synced
- +);
State ($online)Rendered HTMLMemory Management
true<div class="flex..."><span class="w-3..."></span><p class="text-bold">John</p></div>Watcher active
false<div class="flex..."><span hidden class="w-3..."></span><p class="text-gray-400">John</p></div>Attribute synced
+ \ No newline at end of file diff --git a/docs/api/watch.html b/docs/api/watch.html index 1214407..5453ada 100644 --- a/docs/api/watch.html +++ b/docs/api/watch.html @@ -19,7 +19,7 @@ -
Skip to content

⚡ Reactivity Control: $.watch( )

The $.watch function is the reactive engine of SigPro. It allows you to execute code automatically when signals change. $.watch is polymorphic: it can track dependencies automatically or follow an explicit list.

🛠 Function Signature

typescript
// Automatic Mode (Magic Tracking)
+    
Skip to content

⚡ Reactivity Control: $.watch( )

The $.watch function is the reactive engine of SigPro. It allows you to execute code automatically when signals change. $.watch is polymorphic: it can track dependencies automatically or follow an explicit list.

🛠 Function Signature

typescript
// Automatic Mode (Magic Tracking)
 $.watch(callback: Function): StopFunction
 
 // Explicit Mode (Isolated Dependencies)
@@ -51,8 +51,8 @@
 
 // This triggers only ONE re-run.
 a(1);
-b(2);
- +b(2);
+ \ No newline at end of file diff --git a/docs/assets/api_for.md.CGMDz0Px.js b/docs/assets/api_for.md.CGMDz0Px.js new file mode 100644 index 0000000..13b0f2f --- /dev/null +++ b/docs/assets/api_for.md.CGMDz0Px.js @@ -0,0 +1,19 @@ +import{_ as i,o as t,c as a,ae as e}from"./chunks/framework.C8AWLET_.js";const g=JSON.parse('{"title":"♻️ Reactive Lists: $.for( )","description":"","frontmatter":{},"headers":[],"relativePath":"api/for.md","filePath":"api/for.md"}'),n={name:"api/for.md"};function l(h,s,r,p,k,d){return t(),a("div",null,[...s[0]||(s[0]=[e(`

♻️ Reactive Lists: $.for( )

The $.for function is a high-performance list renderer. It maps an array (or a Signal containing an array) to DOM nodes. Unlike a simple .map(), $.for is keyed, meaning it only updates, moves, or deletes the specific items that changed.

🛠️ Function Signature

typescript
$.for(
+  source: Signal<any[]> | Function | any[], 
+  render: (item: any, index: number) => HTMLElement, 
+  keyFn: (item: any, index: number) => string | number
+): HTMLElement
ParameterTypeRequiredDescription
sourceSignalYesThe reactive array to iterate over.
renderFunctionYesA function that returns a component or Node for each item.
keyFnFunctionYesA function to extract a unique ID for each item (crucial for performance).

Returns: A div element with display: contents containing the live list.


📖 Usage Patterns

1. Basic Keyed List

Always use a unique property (like an id) as a key to ensure SigPro doesn't recreate nodes unnecessarily.

javascript
const users = $([
+  { id: 1, name: "Alice" },
+  { id: 2, name: "Bob" }
+]);
+
+Ul({ class: "list" }, [
+  $.for(users, 
+    (user) => Li({ class: "p-2" }, user.name),
+    (user) => user.id
+  )
+]);

2. Handling Primitive Arrays

If your array contains simple strings or numbers, you can use the value itself or the index as a key (though the index is less efficient for reordering).

javascript
const tags = $(["Tech", "JS", "Web"]);
+
+Div({ class: "flex gap-1" }, [
+  $.for(tags, (tag) => Badge(tag), (tag) => tag)
+]);

🏗️ How it Works (The Reconciliation)

When the source signal changes, $.for performs the following steps:

  1. Key Diffing: It compares the new keys with the previous ones stored in an internal Map.
  2. Node Reuse: If a key already exists, the DOM node is reused and moved to its new position. No new elements are created.
  3. Cleanup: If a key disappears from the list, SigPro calls .destroy() on that specific item's instance. This stops all its internal watchers and removes its DOM nodes.

💡 Performance Tips

  • Stable Keys: Never use Math.random() as a key. This will force SigPro to destroy and recreate the entire list on every update, killing performance.
  • Component Encapsulation: If each item in your list has its own complex internal state, $.for ensures that state is preserved even if the list is reordered, as long as the key remains the same.

🧪 Summary Comparison

FeatureStandard Array.mapSigPro $.for
Re-renderRe-renders everythingOnly updates changes
DOM NodesRe-created every timeReused via Keys
MemoryPotential leaksAutomatic Cleanup
StateLost on re-renderPreserved per item
`,24)])])}const E=i(n,[["render",l]]);export{g as __pageData,E as default}; diff --git a/docs/assets/api_for.md.CGMDz0Px.lean.js b/docs/assets/api_for.md.CGMDz0Px.lean.js new file mode 100644 index 0000000..66336f0 --- /dev/null +++ b/docs/assets/api_for.md.CGMDz0Px.lean.js @@ -0,0 +1 @@ +import{_ as i,o as t,c as a,ae as e}from"./chunks/framework.C8AWLET_.js";const g=JSON.parse('{"title":"♻️ Reactive Lists: $.for( )","description":"","frontmatter":{},"headers":[],"relativePath":"api/for.md","filePath":"api/for.md"}'),n={name:"api/for.md"};function l(h,s,r,p,k,d){return t(),a("div",null,[...s[0]||(s[0]=[e("",24)])])}const E=i(n,[["render",l]]);export{g as __pageData,E as default}; diff --git a/docs/assets/api_if.md.C-36XjK0.js b/docs/assets/api_if.md.C-36XjK0.js new file mode 100644 index 0000000..d83340d --- /dev/null +++ b/docs/assets/api_if.md.C-36XjK0.js @@ -0,0 +1,19 @@ +import{_ as i,o as t,c as a,ae as e}from"./chunks/framework.C8AWLET_.js";const g=JSON.parse('{"title":"🔀 Reactive Branching: $.if( )","description":"","frontmatter":{},"headers":[],"relativePath":"api/if.md","filePath":"api/if.md"}'),n={name:"api/if.md"};function l(h,s,p,r,o,d){return t(),a("div",null,[...s[0]||(s[0]=[e(`

🔀 Reactive Branching: $.if( )

The $.if function is a reactive control flow operator. It manages the conditional rendering of components, ensuring that only the active branch exists in the DOM and in memory.

🛠️ Function Signature

typescript
$.if(
+  condition: Signal<boolean> | Function, 
+  thenVal: Component | Node, 
+  otherwiseVal?: Component | Node
+): HTMLElement
ParameterTypeRequiredDescription
conditionSignalYesA reactive source that determines which branch to render.
thenValanyYesThe content to show when the condition is truthy.
otherwiseValanyNoThe content to show when the condition is falsy (defaults to null).

Returns: A div element with display: contents that acts as a reactive portal for the branches.


📖 Usage Patterns

1. Simple Toggle

The most common use case is showing or hiding a single element based on a state.

javascript
const isVisible = $(false);
+
+Div([
+  Button({ onclick: () => isVisible(!isVisible()) }, "Toggle Message"),
+  
+  $.if(isVisible, 
+    P("Now you see me!"), 
+    P("Now you don't...")
+  )
+]);

2. Lazy Component Loading

Unlike using a hidden class (CSS display: none), $.if is lazy. The branch that isn't active is never created. This saves memory and initial processing time.

javascript
$.if(() => user.isLogged(), 
+  () => Dashboard(), // Only executed if logged in
+  () => LoginGate()  // Only executed if guest
+)

🧹 Automatic Cleanup

One of the core strengths of $.if is its integrated Cleanup logic. SigPro ensures that when a branch is swapped out, it is completely purged.

  1. Stop Watchers: All $.watch calls inside the inactive branch are permanently stopped.
  2. Unbind Events: Event listeners attached via $.html are removed.
  3. Recursive Sweep: SigPro performs a deep "sweep" of the removed branch to ensure no nested reactive effects remain active.

💡 Best Practices

  • Function Wrappers: If your branches are heavy (e.g., they contain complex components), wrap them in a function () => MyComponent(). This prevents the component from being initialized until the condition actually meets its requirement.
  • Logical Expressions: You can pass a complex computed function as the condition:
    javascript
    $.if(() => count() > 10 && status() === 'ready', 
    +  Span("Threshold reached!")
    +)

🏗️ Technical Comparison

FeatureStandard CSS hiddenSigPro $.if
DOM PresenceAlways presentOnly if active
ReactivityStill processing in backgroundPaused/Destroyed
Memory usageHigherOptimized
CleanupManualAutomatic
`,24)])])}const c=i(n,[["render",l]]);export{g as __pageData,c as default}; diff --git a/docs/assets/api_if.md.C-36XjK0.lean.js b/docs/assets/api_if.md.C-36XjK0.lean.js new file mode 100644 index 0000000..dec52e9 --- /dev/null +++ b/docs/assets/api_if.md.C-36XjK0.lean.js @@ -0,0 +1 @@ +import{_ as i,o as t,c as a,ae as e}from"./chunks/framework.C8AWLET_.js";const g=JSON.parse('{"title":"🔀 Reactive Branching: $.if( )","description":"","frontmatter":{},"headers":[],"relativePath":"api/if.md","filePath":"api/if.md"}'),n={name:"api/if.md"};function l(h,s,p,r,o,d){return t(),a("div",null,[...s[0]||(s[0]=[e("",24)])])}const c=i(n,[["render",l]]);export{g as __pageData,c as default}; diff --git a/docs/assets/api_quick.md.Dw-DUc7L.js b/docs/assets/api_quick.md.D3C2EJww.js similarity index 97% rename from docs/assets/api_quick.md.Dw-DUc7L.js rename to docs/assets/api_quick.md.D3C2EJww.js index 88cb436..4208582 100644 --- a/docs/assets/api_quick.md.Dw-DUc7L.js +++ b/docs/assets/api_quick.md.D3C2EJww.js @@ -1 +1 @@ -import{_ as e,o as a,c as n,ae as l}from"./chunks/framework.C8AWLET_.js";const f=JSON.parse('{"title":"⚡ Quick API Reference","description":"","frontmatter":{},"headers":[],"relativePath":"api/quick.md","filePath":"api/quick.md"}'),o={name:"api/quick.md"};function d(s,t,r,i,c,g){return a(),n("div",null,[...t[0]||(t[0]=[l('

⚡ Quick API Reference

SigPro is a high-performance micro-framework that updates the Real DOM surgically. No Virtual DOM, no unnecessary re-renders, and built-in Cleanup (memory cleanup).

🟢 Core Functions

FunctionSignatureDescription
$(val, key?)(any, string?) => SignalCreates a Signal. If key is provided, it persists in localStorage.
$(fn)(function) => ComputedCreates a Computed Signal that auto-updates when its dependencies change.
$.watch(fn)(function) => stopFnAutomatic Mode: Tracks any signal touched inside. Returns a stop function.
$.watch(deps, fn)(Array, function) => stopFnExplicit Mode: Only runs when signals in deps change. Used for Cleanup.
$.html(tag, props, kids)(string, obj, any) => ElementThe low-level DOM factory. Attaches ._cleanups to every element.
$.If(cond, then, else?)(Signal, fn, fn?) => NodeReactive conditional. Automatically destroys the "else" branch memory.
$.For(list, itemFn)(Signal, fn) => NodeOptimized list renderer. Manages individual item lifecycles.
$.router(routes)(Array) => ElementHash-based SPA router. Uses Explicit Watch to prevent memory leaks.
$.mount(node, target)(any, string|Node) => RuntimeEntry point. Creates a root instance with .destroy() capabilities.

🏗️ Element Constructors (Tags)

SigPro provides PascalCase wrappers for all standard HTML5 tags (e.g., Div, Span, Button).

Syntax Pattern

javascript
Tag({ attributes }, [children])

Attribute & Content Handling

PatternCode ExampleBehavior
Staticclass: "text-red"Standard HTML attribute string.
Reactivedisabled: isLoadingUpdates automatically via internal $.watch.
Two-way$value: usernameBinding Operator: Syncs input $\\leftrightarrow$ signal both ways.
TextP({}, () => count())Updates text node surgically without re-rendering the P.
Booleanhidden: isHiddenToggles the attribute based on signal truthiness.
',11)])])}const u=e(o,[["render",d]]);export{f as __pageData,u as default}; +import{_ as e,o as a,c as n,ae as l}from"./chunks/framework.C8AWLET_.js";const f=JSON.parse('{"title":"⚡ Quick API Reference","description":"","frontmatter":{},"headers":[],"relativePath":"api/quick.md","filePath":"api/quick.md"}'),o={name:"api/quick.md"};function d(s,t,r,i,c,g){return a(),n("div",null,[...t[0]||(t[0]=[l('

⚡ Quick API Reference

SigPro is a high-performance micro-framework that updates the Real DOM surgically. No Virtual DOM, no unnecessary re-renders, and built-in Cleanup (memory cleanup).

🟢 Core Functions

FunctionSignatureDescription
$(val, key?)(any, string?) => SignalCreates a Signal. If key is provided, it persists in localStorage.
$(fn)(function) => ComputedCreates a Computed Signal that auto-updates when its dependencies change.
$.watch(fn)(function) => stopFnAutomatic Mode: Tracks any signal touched inside. Returns a stop function.
$.watch(deps, fn)(Array, function) => stopFnExplicit Mode: Only runs when signals in deps change. Used for Cleanup.
$.html(tag, props, kids)(string, obj, any) => ElementThe low-level DOM factory. Attaches ._cleanups to every element.
$.if(cond, then, else?)(Signal, fn, fn?) => NodeReactive conditional. Automatically destroys the "else" branch memory.
$.for(list, itemFn)(Signal, fn) => NodeOptimized list renderer. Manages individual item lifecycles.
$.router(routes)(Array) => ElementHash-based SPA router. Uses Explicit Watch to prevent memory leaks.
$.mount(node, target)(any, string|Node) => RuntimeEntry point. Creates a root instance with .destroy() capabilities.

🏗️ Element Constructors (Tags)

SigPro provides PascalCase wrappers for all standard HTML5 tags (e.g., Div, Span, Button).

Syntax Pattern

javascript
Tag({ attributes }, [children])

Attribute & Content Handling

PatternCode ExampleBehavior
Staticclass: "text-red"Standard HTML attribute string.
Reactivedisabled: isLoadingUpdates automatically via internal $.watch.
Two-way$value: usernameBinding Operator: Syncs input $\\leftrightarrow$ signal both ways.
TextP({}, () => count())Updates text node surgically without re-rendering the P.
Booleanhidden: isHiddenToggles the attribute based on signal truthiness.
',11)])])}const u=e(o,[["render",d]]);export{f as __pageData,u as default}; diff --git a/docs/assets/api_quick.md.Dw-DUc7L.lean.js b/docs/assets/api_quick.md.D3C2EJww.lean.js similarity index 100% rename from docs/assets/api_quick.md.Dw-DUc7L.lean.js rename to docs/assets/api_quick.md.D3C2EJww.lean.js diff --git a/docs/assets/install.md.HK-a2_Fb.js b/docs/assets/install.md.C1tyiPaQ.js similarity index 96% rename from docs/assets/install.md.HK-a2_Fb.js rename to docs/assets/install.md.C1tyiPaQ.js index b68b91f..aaecd8a 100644 --- a/docs/assets/install.md.HK-a2_Fb.js +++ b/docs/assets/install.md.C1tyiPaQ.js @@ -1,11 +1,11 @@ -import{_ as i,o as a,c as t,ae as n}from"./chunks/framework.C8AWLET_.js";const g=JSON.parse('{"title":"Installation & Setup","description":"","frontmatter":{},"headers":[],"relativePath":"install.md","filePath":"install.md"}'),l={name:"install.md"};function e(h,s,p,k,r,d){return a(),t("div",null,[...s[0]||(s[0]=[n(`

Installation & Setup

SigPro is designed to be drop-in ready. Whether you are building a complex application with a bundler or a simple reactive widget in a single HTML file, SigPro scales with your needs.

1. Installation

Choose the method that best fits your workflow:

bash
npm install sigpro
bash
pnpm add sigpro
bash
yarn add sigpro
bash
bun add sigpro
html
<script type="module">
+import{_ as i,o as a,c as t,ae as n}from"./chunks/framework.C8AWLET_.js";const g=JSON.parse('{"title":"Installation & Setup","description":"","frontmatter":{},"headers":[],"relativePath":"install.md","filePath":"install.md"}'),l={name:"install.md"};function e(h,s,p,k,r,d){return a(),t("div",null,[...s[0]||(s[0]=[n(`

Installation & Setup

SigPro is designed to be drop-in ready. Whether you are building a complex application with a bundler or a simple reactive widget in a single HTML file, SigPro scales with your needs.

1. Installation

Choose the method that best fits your workflow:

bash
npm install sigpro
bash
pnpm add sigpro
bash
yarn add sigpro
bash
bun add sigpro
html
<script type="module">
   // Import the core and UI components
   import { $ } from 'https://cdn.jsdelivr.net/npm/sigpro@latest/+esm';
   import { UI } from 'https://cdn.jsdelivr.net/npm/sigpro@latest/ui/+esm';
   
   // Initialize UI components globally
   UI($);
-</script>

2. Quick Start Examples

SigPro uses PascalCase for Tag Helpers (e.g., Div, Button) to provide a clean, component-like syntax without needing JSX.

javascript
// File: App.js
+</script>

2. Quick Start Examples

SigPro uses PascalCase for Tag Helpers (e.g., Div, Button) to provide a clean, component-like syntax without needing JSX.

javascript
// File: App.js
 import { $ } from 'sigpro'; 
 
 export const App = () => {
diff --git a/docs/assets/install.md.HK-a2_Fb.lean.js b/docs/assets/install.md.C1tyiPaQ.lean.js
similarity index 100%
rename from docs/assets/install.md.HK-a2_Fb.lean.js
rename to docs/assets/install.md.C1tyiPaQ.lean.js
diff --git a/docs/hashmap.json b/docs/hashmap.json
index 8515533..44f9799 100644
--- a/docs/hashmap.json
+++ b/docs/hashmap.json
@@ -1 +1 @@
-{"api_html.md":"DSCIaSlE","api_mount.md":"CoM2SFqU","api_quick.md":"Dw-DUc7L","api_router.md":"Cn98LjXO","api_signal.md":"BmorvARW","api_tags.md":"BKWIb8mV","api_watch.md":"BEM6Qssx","index.md":"By6smViD","install.md":"HK-a2_Fb","ui_quick.md":"CsppjR8J","vite_plugin.md":"CTs8LDIL"}
+{"api_for.md":"CGMDz0Px","api_html.md":"DSCIaSlE","api_if.md":"C-36XjK0","api_mount.md":"CoM2SFqU","api_quick.md":"D3C2EJww","api_router.md":"Cn98LjXO","api_signal.md":"BmorvARW","api_tags.md":"BKWIb8mV","api_watch.md":"BEM6Qssx","index.md":"By6smViD","install.md":"C1tyiPaQ","ui_quick.md":"CsppjR8J","vite_plugin.md":"CTs8LDIL"}
diff --git a/docs/index.html b/docs/index.html
index 90d1828..7017335 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -20,7 +20,7 @@
   
   
     
Skip to content

SigProAtomic Unified Reactive Engine

High-precision atomic reactivity. No Virtual DOM. No compiler. No dependencies.

SigPro Logo

Redefining Modern Reactivity

SigPro is not just another framework; it is a high-performance engine. While other libraries add layers of abstraction that slow down execution, SigPro returns to the essence of the web, leveraging the power of modern browser engines.

Why SigPro?

⚡️ Surgical DOM Efficiency

Unlike React or Vue, SigPro doesn't compare element trees. When a signal changes, SigPro knows exactly which DOM node depends on it and updates it instantly. It is reactive precision at its finest.

🔌 Modular Plugin System

The core is sacred. Any extra functionality—Routing, UI Helpers, or State Persistence—is integrated through a polymorphic plugin system. Load only what your application truly needs.

💾 Native Persistence

SigPro features first-class support for localStorage. Synchronizing your application state with persistent storage is as simple as providing a key when initializing your Signal.

🚦 Built-in Hash Routing

A robust routing system that supports Native Lazy Loading out of the box. Load your components only when the user navigates to them, keeping initial load times near zero.


The "No-Build" Philosophy

In an ecosystem obsessed with compilers, SigPro bets on standardization. Write code today that will still run 10 years from now, without depending on build tools that will eventually become obsolete.

"The best way to optimize code is to not have to process it at all."


Community & Vision

SigPro is an open-source project focused on simplicity and extreme speed. Designed for developers who love the web platform and hate unnecessary "bloatware".

text
Built with ❤️ by NatxoCC for the Modern Web.
- + \ No newline at end of file diff --git a/docs/install.html b/docs/install.html index b699933..b0b14f6 100644 --- a/docs/install.html +++ b/docs/install.html @@ -13,20 +13,20 @@ - + -
Skip to content

Installation & Setup

SigPro is designed to be drop-in ready. Whether you are building a complex application with a bundler or a simple reactive widget in a single HTML file, SigPro scales with your needs.

1. Installation

Choose the method that best fits your workflow:

bash
npm install sigpro
bash
pnpm add sigpro
bash
yarn add sigpro
bash
bun add sigpro
html
<script type="module">
+    
Skip to content

Installation & Setup

SigPro is designed to be drop-in ready. Whether you are building a complex application with a bundler or a simple reactive widget in a single HTML file, SigPro scales with your needs.

1. Installation

Choose the method that best fits your workflow:

bash
npm install sigpro
bash
pnpm add sigpro
bash
yarn add sigpro
bash
bun add sigpro
html
<script type="module">
   // Import the core and UI components
   import { $ } from 'https://cdn.jsdelivr.net/npm/sigpro@latest/+esm';
   import { UI } from 'https://cdn.jsdelivr.net/npm/sigpro@latest/ui/+esm';
   
   // Initialize UI components globally
   UI($);
-</script>

2. Quick Start Examples

SigPro uses PascalCase for Tag Helpers (e.g., Div, Button) to provide a clean, component-like syntax without needing JSX.

javascript
// File: App.js
+</script>

2. Quick Start Examples

SigPro uses PascalCase for Tag Helpers (e.g., Div, Button) to provide a clean, component-like syntax without needing JSX.

javascript
// File: App.js
 import { $ } from 'sigpro'; 
 
 export const App = () => {
@@ -71,7 +71,7 @@
   </script>
 </body>
 </html>

3. Global by Design

One of SigPro's core strengths is its Global API, which eliminates "Import Hell".

  • The $ Function: Once loaded, it attaches itself to window.$. It handles state, effects, and DOM mounting.
  • Tag Helpers (PascalCase): Common HTML tags (Div, Span, Button, Input, etc.) are automatically registered in the global scope.
  • Custom Components: We recommend using PascalCase (e.g., UserCard) or prefixes like _Input to keep your code organized and distinguish your logic from standard tags.

4. Why no build step?

Because SigPro uses native ES Modules and standard JavaScript functions to generate the DOM, you don't actually need a compiler like Babel or a transformer for JSX.

  • Development: Just save and refresh. Pure JS, no "transpilation" required.
  • Performance: Extremely lightweight. Use any modern bundler (Vite, esbuild) only when you are ready to minify and tree-shake for production.

5. Why SigPro? (The Competitive Edge)

SigPro stands out by removing the "Build Step" tax and the "Virtual DOM" overhead. It is the closest you can get to writing raw HTML/JS while maintaining modern reactivity.

FeatureSigProSolidJSSvelteReactVue
Bundle Size~2KB~7KB~4KB~40KB+~30KB
DOM StrategyDirect DOMDirect DOMCompiled DOMVirtual DOMVirtual DOM
ReactivityFine-grainedFine-grainedCompiledRe-rendersProxies
Build StepOptionalRequiredRequiredRequiredOptional
Learning CurveMinimalMediumLowHighMedium
InitializationUltra-FastVery FastFastSlowMedium

6. Key Advantages

  • Extreme Performance: No Virtual DOM reconciliation. SigPro updates the specific node or attribute instantly when a Signal changes.
  • Fine-Grained Reactivity: State changes only trigger updates where the data is actually used, not on the entire component.
  • Native Web Standards: Everything is a standard JS function. No custom template syntax to learn.
  • Zero Magic: No hidden compilers. What you write is what runs in the browser.
  • Global by Design: Tag Helpers and the $ function are available globally to eliminate "Import Hell" and keep your code clean.

7. Summary

SigPro isn't just another framework; it's a bridge to the native web. By using standard ES Modules and functional DOM generation, you gain the benefits of a modern library with the weight of a utility script.

Because, in the end... why fight the web when we can embrace it?

- + \ No newline at end of file diff --git a/docs/ui/quick.html b/docs/ui/quick.html index b906680..044734f 100644 --- a/docs/ui/quick.html +++ b/docs/ui/quick.html @@ -19,7 +19,7 @@ -
Skip to content

🧩 UI Components (WIP)

Status: Work In Progress. > These are high-level, complex visual components designed to speed up development. They replace native HTML elements with "superpowered" versions that handle their own internal logic, reactivity, and professional styling.

⚠️ Prerequisites

To ensure all components render correctly with their reactive themes and states, your project must have the following versions installed:

  • Tailwind CSS v4+: For the new engine performance and modern CSS variables.
  • DaisyUI v5+: Required for the updated theme-selectors and improved component classes used in the SigPro UI library.

1. What are UI Components?

Unlike Tag Helpers (which are just functional mirrors of HTML tags), SigPro UI Components are smart abstractions:

  • Stateful: They manage complex internal states (like date ranges, search filtering, or API lifecycles).
  • Reactive: Attributes prefixed with $ are automatically tracked via $.watch.
  • Self-Sane: They automatically use ._cleanups to destroy observers or event listeners when removed from the DOM.
  • Themed: Fully compatible with the DaisyUI v5 theme system and Tailwind v4 utility classes.

2. The UI Registry (Available Now)

CategoryComponents
Forms & InputsButton, Input, Select, Autocomplete, Datepicker, Colorpicker, CheckBox, Radio, Range, Rating, Swap
FeedbackAlert, Toast, Modal, Loading, Badge, Tooltip, Indicator
NavigationNavbar, Menu, Drawer, Tabs, Accordion, Dropdown
Data & LayoutRequest, Response, Grid (AG-Grid), List, Stack, Timeline, Stat, Fieldset, Fab

3. Examples with "Superpowers"

A. The Declarative API Flow (Request & Response)

Instead of manually managing loading and error flags, use these together to handle data fetching elegantly.

javascript
// 1. Define the request (it tracks dependencies automatically)
+    
Skip to content

🧩 UI Components (WIP)

Status: Work In Progress. > These are high-level, complex visual components designed to speed up development. They replace native HTML elements with "superpowered" versions that handle their own internal logic, reactivity, and professional styling.

⚠️ Prerequisites

To ensure all components render correctly with their reactive themes and states, your project must have the following versions installed:

  • Tailwind CSS v4+: For the new engine performance and modern CSS variables.
  • DaisyUI v5+: Required for the updated theme-selectors and improved component classes used in the SigPro UI library.

1. What are UI Components?

Unlike Tag Helpers (which are just functional mirrors of HTML tags), SigPro UI Components are smart abstractions:

  • Stateful: They manage complex internal states (like date ranges, search filtering, or API lifecycles).
  • Reactive: Attributes prefixed with $ are automatically tracked via $.watch.
  • Self-Sane: They automatically use ._cleanups to destroy observers or event listeners when removed from the DOM.
  • Themed: Fully compatible with the DaisyUI v5 theme system and Tailwind v4 utility classes.

2. The UI Registry (Available Now)

CategoryComponents
Forms & InputsButton, Input, Select, Autocomplete, Datepicker, Colorpicker, CheckBox, Radio, Range, Rating, Swap
FeedbackAlert, Toast, Modal, Loading, Badge, Tooltip, Indicator
NavigationNavbar, Menu, Drawer, Tabs, Accordion, Dropdown
Data & LayoutRequest, Response, Grid (AG-Grid), List, Stack, Timeline, Stat, Fieldset, Fab

3. Examples with "Superpowers"

A. The Declarative API Flow (Request & Response)

Instead of manually managing loading and error flags, use these together to handle data fetching elegantly.

javascript
// 1. Define the request (it tracks dependencies automatically)
 const userProfile = Request(
   () => `https://api.example.com/user/${userId()}`
 );
@@ -63,7 +63,7 @@
 
 // Access translated strings (Returns a signal that tracks the current locale)
 const t = tt("confirm");

5. Best Practices

  • Use $ for Reactivity: If a property starts with $, the component expects a Signal (e.g., $value: mySignal).
  • Automatic Cleaning: You don't need to manually destroy these components if they are inside a $.If or $.For. SigPro's core will "sweep" their internal watchers automatically.
  • Manual Cleanups: If you build custom components using setInterval or third-party observers, always add the stop functions to the element's ._cleanups Set.
- + \ No newline at end of file diff --git a/docs/vite/plugin.html b/docs/vite/plugin.html index ed3b7f1..1559d33 100644 --- a/docs/vite/plugin.html +++ b/docs/vite/plugin.html @@ -19,7 +19,7 @@ -
Skip to content

Vite Plugin: File-based Routing

The sigproRouter plugin for Vite automates route generation by scanning your pages directory. It creates a virtual module that you can import directly into your code, eliminating the need to maintain a manual routes array.

1. Project Structure

To use the plugin, organize your files within the src/pages directory. The folder hierarchy directly determines your application's URL structure. SigPro uses brackets [param] for dynamic segments.

text
my-sigpro-app/
+    
Skip to content

Vite Plugin: File-based Routing

The sigproRouter plugin for Vite automates route generation by scanning your pages directory. It creates a virtual module that you can import directly into your code, eliminating the need to maintain a manual routes array.

1. Project Structure

To use the plugin, organize your files within the src/pages directory. The folder hierarchy directly determines your application's URL structure. SigPro uses brackets [param] for dynamic segments.

text
my-sigpro-app/
 ├── src/
 │   ├── pages/
 │   │   ├── index.js          →  #/
@@ -68,7 +68,7 @@
   { path: '/users/:id', component: () => import('/src/pages/users/[id].js') },
   // ...
 ];

Because it uses dynamic import(), Vite automatically performs Code Splitting, meaning each page is its own small JS file that only loads when the user navigates to it.

- + \ No newline at end of file diff --git a/src/docs/.vitepress/config.js b/src/docs/.vitepress/config.js index b1937cc..5c57f93 100644 --- a/src/docs/.vitepress/config.js +++ b/src/docs/.vitepress/config.js @@ -42,9 +42,11 @@ export default defineConfig({ { text: 'Quick Start', link: '/api/quick' }, { text: '$', link: '/api/signal' }, { text: '$.watch', link: '/api/watch' }, - { text: '$.html', link: '/api/html' }, + { text: '$.if', link: '/api/if' }, + { text: '$.for', link: '/api/for' }, { text: '$.router', link: '/api/router' }, { text: '$.mount', link: '/api/mount' }, + { text: '$.html', link: '/api/html' }, { text: 'Tags', link: '/api/tags' }, ] }, diff --git a/src/docs/api/for.md b/src/docs/api/for.md new file mode 100644 index 0000000..588229a --- /dev/null +++ b/src/docs/api/for.md @@ -0,0 +1,83 @@ +# ♻️ Reactive Lists: `$.for( )` + +The `$.for` function is a high-performance list renderer. It maps an array (or a Signal containing an array) to DOM nodes. Unlike a simple `.map()`, `$.for` is **keyed**, meaning it only updates, moves, or deletes the specific items that changed. + +## 🛠️ Function Signature + +```typescript +$.for( + source: Signal | Function | any[], + render: (item: any, index: number) => HTMLElement, + keyFn: (item: any, index: number) => string | number +): HTMLElement +``` + +| Parameter | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **`source`** | `Signal` | Yes | The reactive array to iterate over. | +| **`render`** | `Function` | Yes | A function that returns a component or Node for each item. | +| **`keyFn`** | `Function` | Yes | A function to extract a **unique ID** for each item (crucial for performance). | + +**Returns:** A `div` element with `display: contents` containing the live list. + +--- + +## 📖 Usage Patterns + +### 1. Basic Keyed List +Always use a unique property (like an `id`) as a key to ensure SigPro doesn't recreate nodes unnecessarily. + +```javascript +const users = $([ + { id: 1, name: "Alice" }, + { id: 2, name: "Bob" } +]); + +Ul({ class: "list" }, [ + $.for(users, + (user) => Li({ class: "p-2" }, user.name), + (user) => user.id + ) +]); +``` + +### 2. Handling Primitive Arrays +If your array contains simple strings or numbers, you can use the value itself or the index as a key (though the index is less efficient for reordering). + +```javascript +const tags = $(["Tech", "JS", "Web"]); + +Div({ class: "flex gap-1" }, [ + $.for(tags, (tag) => Badge(tag), (tag) => tag) +]); +``` + +--- + +## 🏗️ How it Works (The Reconciliation) + +When the `source` signal changes, `$.for` performs the following steps: + +1. **Key Diffing**: It compares the new keys with the previous ones stored in an internal `Map`. +2. **Node Reuse**: If a key already exists, the DOM node is **reused** and moved to its new position. No new elements are created. +3. **Cleanup**: If a key disappears from the list, SigPro calls `.destroy()` on that specific item's instance. This stops all its internal watchers and removes its DOM nodes. + + + +--- + +## 💡 Performance Tips + +* **Stable Keys**: Never use `Math.random()` as a key. This will force SigPro to destroy and recreate the entire list on every update, killing performance. +* **Component Encapsulation**: If each item in your list has its own complex internal state, `$.for` ensures that state is preserved even if the list is reordered, as long as the key remains the same. + +--- + +## 🧪 Summary Comparison + +| Feature | Standard `Array.map` | SigPro `$.for` | +| :--- | :--- | :--- | +| **Re-render** | Re-renders everything | Only updates changes | +| **DOM Nodes** | Re-created every time | **Reused via Keys** | +| **Memory** | Potential leaks | **Automatic Cleanup** | +| **State** | Lost on re-render | **Preserved per item** | diff --git a/src/docs/api/if.md b/src/docs/api/if.md new file mode 100644 index 0000000..5326d1a --- /dev/null +++ b/src/docs/api/if.md @@ -0,0 +1,88 @@ + +# 🔀 Reactive Branching: `$.if( )` + +The `$.if` function is a reactive control flow operator. It manages the conditional rendering of components, ensuring that only the active branch exists in the DOM and in memory. + +## 🛠️ Function Signature + +```typescript +$.if( + condition: Signal | Function, + thenVal: Component | Node, + otherwiseVal?: Component | Node +): HTMLElement +``` + +| Parameter | Type | Required | Description | +| :--- | :--- | :--- | :--- | +| **`condition`** | `Signal` | Yes | A reactive source that determines which branch to render. | +| **`thenVal`** | `any` | Yes | The content to show when the condition is **truthy**. | +| **`otherwiseVal`** | `any` | No | The content to show when the condition is **falsy** (defaults to null). | + +**Returns:** A `div` element with `display: contents` that acts as a reactive portal for the branches. + +--- + +## 📖 Usage Patterns + +### 1. Simple Toggle +The most common use case is showing or hiding a single element based on a state. + +```javascript +const isVisible = $(false); + +Div([ + Button({ onclick: () => isVisible(!isVisible()) }, "Toggle Message"), + + $.if(isVisible, + P("Now you see me!"), + P("Now you don't...") + ) +]); +``` + +### 2. Lazy Component Loading +Unlike using a hidden class (CSS `display: none`), `$.if` is **lazy**. The branch that isn't active **is never created**. This saves memory and initial processing time. + +```javascript +$.if(() => user.isLogged(), + () => Dashboard(), // Only executed if logged in + () => LoginGate() // Only executed if guest +) +``` + +--- + +## 🧹 Automatic Cleanup + +One of the core strengths of `$.if` is its integrated **Cleanup** logic. SigPro ensures that when a branch is swapped out, it is completely purged. + +1. **Stop Watchers**: All `$.watch` calls inside the inactive branch are permanently stopped. +2. **Unbind Events**: Event listeners attached via `$.html` are removed. +3. **Recursive Sweep**: SigPro performs a deep "sweep" of the removed branch to ensure no nested reactive effects remain active. + + + +--- + +## 💡 Best Practices + +* **Function Wrappers**: If your branches are heavy (e.g., they contain complex components), wrap them in a function `() => MyComponent()`. This prevents the component from being initialized until the condition actually meets its requirement. +* **Logical Expressions**: You can pass a complex computed function as the condition: + ```javascript + $.if(() => count() > 10 && status() === 'ready', + Span("Threshold reached!") + ) + ``` + +--- + +## 🏗️ Technical Comparison + +| Feature | Standard CSS `hidden` | SigPro `$.if` | +| :--- | :--- | :--- | +| **DOM Presence** | Always present | Only if active | +| **Reactivity** | Still processing in background | **Paused/Destroyed** | +| **Memory usage** | Higher | **Optimized** | +| **Cleanup** | Manual | **Automatic** | + diff --git a/src/docs/api/quick.md b/src/docs/api/quick.md index 75e5fdb..e5982cd 100644 --- a/src/docs/api/quick.md +++ b/src/docs/api/quick.md @@ -11,8 +11,8 @@ SigPro is a high-performance micro-framework that updates the **Real DOM** surgi | **`$.watch(fn)`** | `(function) => stopFn` | **Automatic Mode:** Tracks any signal touched inside. Returns a stop function. | | **`$.watch(deps, fn)`** | `(Array, function) => stopFn` | **Explicit Mode:** Only runs when signals in `deps` change. Used for Cleanup. | | **`$.html(tag, props, kids)`** | `(string, obj, any) => Element` | The low-level DOM factory. Attaches `._cleanups` to every element. | -| **`$.If(cond, then, else?)`** | `(Signal, fn, fn?) => Node` | Reactive conditional. Automatically destroys the "else" branch memory. | -| **`$.For(list, itemFn)`** | `(Signal, fn) => Node` | Optimized list renderer. Manages individual item lifecycles. | +| **`$.if(cond, then, else?)`** | `(Signal, fn, fn?) => Node` | Reactive conditional. Automatically destroys the "else" branch memory. | +| **`$.for(list, itemFn)`** | `(Signal, fn) => Node` | Optimized list renderer. Manages individual item lifecycles. | | **`$.router(routes)`** | `(Array) => Element` | Hash-based SPA router. Uses Explicit Watch to prevent memory leaks. | | **`$.mount(node, target)`** | `(any, string\|Node) => Runtime` | Entry point. Creates a root instance with `.destroy()` capabilities. |