nuclo 0.2.18 → 0.2.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,14 +1,14 @@
1
1
  # nuclo
2
2
 
3
- **A lightweight DOM framework with reactive UI bindings, mutable state, and explicit updates.**
3
+ **A lightweight, type-safe JS/TS DOM framework with plain mutable state and explicit updates.**
4
4
 
5
- Create elements with plain functions, and pass a function anywhere a value depends on state — that registers a reactive binding Nuclo can reevaluate later. Mutate regular JavaScript values directly, then call `update()` when you want Nuclo to synchronize the DOM. No virtual DOM, no proxies, and no automatic state tracking.
5
+ Create elements with plain functions, and pass a function anywhere a value depends on state — that function is registered so Nuclo can evaluate it again later. Change regular JavaScript values directly, then call `update()` when you want Nuclo to synchronize the DOM. No virtual DOM, no proxies, no signals, and no automatic state tracking.
6
6
 
7
7
  Nuclo's workflow has three parts:
8
8
 
9
- 1. **Create the UI with builder functions** — text, attributes, conditions, and lists can be passed a function whenever they depend on state; this registers a reactive binding.
9
+ 1. **Create the UI with builder functions** — text, attributes, conditions, and lists can be passed a function whenever they depend on state; this registers the function as a state-dependent value.
10
10
  2. **Mutate regular JavaScript state** — no signals, no proxies, no wrapped values. `count++` is just `count++`. Mutating state does not, by itself, touch the DOM.
11
- 3. **Call `update()`** — this explicitly triggers synchronization: Nuclo reevaluates the bindings registered in step 1 and patches the real DOM wherever a result changed.
11
+ 3. **Call `update()`** — this explicitly starts synchronization: Nuclo reevaluates the state-dependent values registered in step 1 and applies changed results to the real DOM.
12
12
 
13
13
  ```ts
14
14
  import 'nuclo';
@@ -28,13 +28,13 @@ render(counter, document.body);
28
28
 
29
29
  ## Why nuclo?
30
30
 
31
- - **Reactive UI Bindings** – Pass a function for any text, attribute, condition, or list that depends on state; Nuclo can reevaluate it later
31
+ - **State-Dependent Values** – Pass a function for any text, attribute, condition, or list that depends on state; Nuclo can evaluate it again later
32
32
  - **Explicit and Predictable** – Reevaluation doesn't happen on mutation — you trigger it yourself with a simple `update()` call
33
33
  - **Real DOM, No Virtual Layer** – Nuclo creates and updates real DOM nodes directly; there's no virtual DOM to diff
34
34
  - **Tiny Footprint** – ~13 KB gzipped, zero dependencies
35
35
  - **Global Tag Builders** – Natural API with global functions for all HTML and SVG elements
36
36
  - **TypeScript-First** – Full type definitions for all 175 HTML and SVG builders
37
- - **Targeted DOM Updates** – `update()` re-runs registered bindings and only touches DOM where values changed
37
+ - **Targeted DOM Updates** – `update()` re-runs registered state-dependent values and only touches DOM where values changed
38
38
  - **Atomic Styling** – Built-in `css()` / `createCss()` with TypeScript autocomplete, theming, and SSR CSS collection
39
39
  - **Server-Side Rendering** – `renderToString()` + `hydrate()` with a lightweight DOM polyfill
40
40
 
@@ -313,12 +313,12 @@ render(app, document.body);
313
313
  **The mental model:**
314
314
 
315
315
  1. Create the UI with builder functions — `h1(...)`, `when()`, `list()`.
316
- 2. Use functions for values that depend on state — `h1(() => \`Count: ${count}\`)`. This registers a reactive binding.
316
+ 2. Use functions for values that depend on state — `h1(() => \`Count: ${count}\`)`. This registers a state-dependent value.
317
317
  3. Mutate regular JavaScript state — `count++`.
318
318
  4. Call `update()`.
319
- 5. Nuclo reevaluates registered bindings and applies the changes to the existing DOM.
319
+ 5. Nuclo reevaluates the registered state-dependent values and applies the changes to the existing DOM.
320
320
 
321
- State mutation and the `update()` call are plain JavaScript: you write `count++` and call `update()` yourself. Nuclo does not watch your variables — nothing reevaluates until `update()` runs. This is explicitly triggered reactivity, not automatic reactivity: the binding from step 2 stays reactive (it can be reevaluated), but only `update()` starts that reevaluation.
321
+ State mutation and the `update()` call are plain JavaScript: you write `count++` and call `update()` yourself. Nuclo does not watch your variables — nothing reevaluates until `update()` runs. The function from step 2 stays registered so it can be evaluated again, but only `update()` starts that evaluation.
322
322
 
323
323
  ### 1. **Explicit Updates**
324
324
 
@@ -361,7 +361,7 @@ user.name = 'Alice'; // triggers update
361
361
 
362
362
  ### 2. **Dynamic Functions**
363
363
 
364
- Zero-arg functions become reactive bindings: Nuclo keeps them registered and can reevaluate them, but only when you call `update()` — mutating the state they read does nothing on its own:
364
+ Zero-arg functions become state-dependent values: Nuclo keeps them registered and can evaluate them again, but only when you call `update()` — mutating the state they read does nothing on its own:
365
365
 
366
366
  ```ts
367
367
  let count = 0;
@@ -736,18 +736,18 @@ These markers identify conditional and list boundaries in the DOM.
736
736
  ### Gotchas
737
737
 
738
738
  **Parameter count decides what a function modifier means.**
739
- A modifier with **zero declared parameters** is treated as reactive text (or a reactive `cn()` className) and is called with no arguments. A modifier with **one or more declared parameters** is a node-modifier function receiving `(element, index)`. Default and rest parameters don't count as declared parameters (`fn.length` is 0), so these are all treated as *reactive text*, not node modifiers:
739
+ A modifier with **zero declared parameters** is treated as dynamic text (or a dynamic `cn()` className) and is called with no arguments. A modifier with **one or more declared parameters** is a node-modifier function receiving `(element, index)`. Default and rest parameters don't count as declared parameters (`fn.length` is 0), so these are all treated as *dynamic text*, not node modifiers:
740
740
 
741
741
  ```ts
742
- div((el = fallback) => el.id); // reactive text — el is undefined!
743
- div((...args) => args[0]); // reactive text — args is empty!
742
+ div((el = fallback) => el.id); // dynamic text — el is undefined!
743
+ div((...args) => args[0]); // dynamic text — args is empty!
744
744
  div((el) => el.id = "x"); // node modifier — el is the element ✓
745
745
  ```
746
746
 
747
747
  If a modifier needs the element, declare it as a plain required parameter.
748
748
 
749
- **Detached nodes lose reactivity.**
750
- Reactive registrations (text, attributes, `list()`, `when()`) are pruned for any node that is disconnected from the DOM when `update()` runs. Re-attaching the node later does **not** restore them. Keep-alive and portal-style patterns should re-render content after re-attaching instead of moving live subtrees between updates.
749
+ **Detached nodes stop updating.**
750
+ Registered state-dependent values (text, attributes, `list()`, `when()`) are pruned for any node that is disconnected from the DOM when `update()` runs. Re-attaching the node later does **not** restore them. Keep-alive and portal-style patterns should rebuild content after re-attaching instead of moving live subtrees between updates.
751
751
 
752
752
  ---
753
753
 
package/package.json CHANGED
@@ -1,13 +1,12 @@
1
1
  {
2
2
  "name": "nuclo",
3
3
  "private": false,
4
- "version": "0.2.18",
5
- "description": "Lightweight DOM library with reactive UI bindings, mutable state, and explicit updates — global tag builders, SSR, hydration, and atomic CSS, no virtual DOM, no compiler.",
4
+ "version": "0.2.19",
5
+ "description": "Lightweight, type-safe DOM library with plain mutable state and explicit updates — global tag builders, SSR, hydration, and atomic CSS, no virtual DOM, no compiler.",
6
6
  "license": "MIT",
7
7
  "author": "Danilo Celestino de Castro (https://github.com/dan2dev)",
8
8
  "keywords": [
9
9
  "dom",
10
- "reactive",
11
10
  "ui",
12
11
  "ssr",
13
12
  "hydration",
@@ -26,7 +26,8 @@ declare global {
26
26
 
27
27
  /**
28
28
  * Hydrates an existing server-rendered DOM tree by walking it in parallel with
29
- * the component tree, reusing existing nodes and re-attaching reactivity.
29
+ * the component tree, reusing existing nodes and re-registering their
30
+ * state-dependent values for future `update()` calls.
30
31
  *
31
32
  * @param nodeModFn The NodeModFn to hydrate (same component used for SSR)
32
33
  * @param parent The parent element containing the SSR HTML (defaults to document.body)
@@ -5,7 +5,7 @@ declare global {
5
5
  // SVG attribute types that accept string values for all SVG properties
6
6
  // This is needed because SVG DOM properties like 'width' are SVGAnimatedLength,
7
7
  // but we set them as strings using setAttribute()
8
- // Supports reactive values (functions) for dynamic attributes
8
+ // Supports state-dependent values (functions) for dynamic attributes
9
9
  export type SVGAttributes = {
10
10
  // Common SVG attributes
11
11
  width?: SVGAttributeValue<string | number>;
@@ -70,7 +70,7 @@ declare global {
70
70
  "clip-path"?: SVGAttributeValue<string>;
71
71
  mask?: SVGAttributeValue<string>;
72
72
 
73
- // Allow any other string attributes (including reactive functions)
73
+ // Allow any other string attributes (including state-dependent functions)
74
74
  // Using a more restrictive type to maintain type safety
75
75
  } & {
76
76
  [K in string]?: SVGAttributeValue;