Skip to content

Add reactive always, when & bind features#661

Open
scriptogre wants to merge 1 commit intobigskysoftware:devfrom
scriptogre:feature/reactivity
Open

Add reactive always, when & bind features#661
scriptogre wants to merge 1 commit intobigskysoftware:devfrom
scriptogre:feature/reactivity

Conversation

@scriptogre
Copy link
Copy Markdown

@scriptogre scriptogre commented Mar 27, 2026

What this enables

<button _="on click increment $count">+1</button>
<button _="on click set $count to 0">Reset</button>
<output _="always put 'Count: ' + $count into me">
<div _="always
          set $subtotal to (#price's value * #qty's value)
          set $total to ($subtotal + $tax)
          put '$' + $total into me
          if $total > 100 add .expensive to me else remove .expensive from me end
        end">
<input type="checkbox" id="dark-toggle" />
<body _="bind .dark and #dark-toggle's checked">

<input type="range" id="slider" />
<input type="number" _="bind my value and #slider's value" />

<input type="radio" name="size" value="S" _="bind $size" />
<input type="radio" name="size" value="M" _="bind $size" />
<input type="radio" name="size" value="L" _="bind $size" />

Three features

Feature Purpose Example
always Declare what should always be true always put '$' + $total into me
when React to changes with side effects when $count changes put it into me
bind Two-way sync bind .dark and #toggle's checked

always

Runs its commands with automatic dependency tracking. When any dependency changes,
the block re-runs top to bottom:

<span _="always put '$' + (#price's value * #qty's value) into me">

<div _="always
          if $active add .on to me
          else remove .on from me end
        end">

For independent tracking, use separate always statements:

<div _="always set $subtotal to (#price's value * #qty's value) end
        always set $total to ($subtotal + $tax) end
        always put '$' + $total into me">

when

Watches an expression, gives you it (the new value):

<output _="when $count changes put it into me">
<div _="when $x or $y changes put it into me">

bind

Two-way sync. Accepts and, with, or to. Left side wins on init:

<body _="bind .dark and #dark-toggle's checked">
<input _="bind my value and #slider's value">
<h1 _="bind @data-title and #title-input's value">
<input _="bind $name" />
<input type="radio" name="x" value="a" _="bind $choice" />

How it works

Single createEffect() primitive. When an effect evaluates, the runtime records
every variable, property, and attribute read. When any change, the effect re-runs.
Effects batch via queueMicrotask, deduplicate with Object.is, and auto-dispose
when the element disconnects.

Tests

89 tests across when.js (40), bind.js (34), always.js (15).

@scriptogre scriptogre changed the title Add reactivity: always, when, and bind features Add reactivity: always, when, and bind features Mar 27, 2026
@scriptogre scriptogre changed the title Add reactivity: always, when, and bind features Add reactive always, when &bind features Mar 27, 2026
@scriptogre scriptogre changed the title Add reactive always, when &bind features Add reactive always, when & bind features Mar 27, 2026
@scriptogre scriptogre force-pushed the feature/reactivity branch 2 times, most recently from 4cd343f to b7274fc Compare March 27, 2026 13:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant