`deka-dom-el` — Signals and reactivity

Handling reactivity in UI via signals.

Using signals to manage reactivity

How a program responds to variable data or user interactions is one of the fundamental problems of programming. If we desire to solve the issue in a declarative manner, signals may be a viable approach.

// when NPM import { S } from "deka-dom-el/signals"; // https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js /** * @type {ddeSignal} * */ /** * @type {ddeActions} * */

# Introducing signals

Using signals, we split program logic into the three parts. Firstly (α), we create a variable (constant) representing reactive value. Somewhere later, we can register (β) a logic reacting to the signal value changes. Similarly, in a remaining part (γ), we can update the signal value.

import { S } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js"; // α — `signal` represents a reactive value const signal= S(0); // β — just reacts on signal changes S.on(signal, console.log); // γ — just updates the value signal(signal()+1); setInterval(()=> signal(signal()+1), 5000);

All this is just an example of Event-driven programming and Publish–subscribe pattern (compare for example with fpubsub library). All three parts can be in some manner independent and still connected to the same reactive entity.

Signals are implemented in the library as functions. To see current value of signal, just call it without any arguments console.log(signal()). To update the signal value, pass any argument signal('a new value'). For listenning the signal value changes, use S.on(signal, console.log).

Similarly to the on function to register DOM events listener. You can use AbortController/AbortSignal to off/stop listenning. For representing “live” piece of code computation pattern:

import { S } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js"; const signal= S(0); // computation pattern const double= S(()=> 2*signal()); const ac= new AbortController(); S.on(signal, v=> console.log("signal", v), { signal: ac.signal }); S.on(double, v=> console.log("double", v), { signal: ac.signal }); signal(signal()+1); const interval= 5000; const id= setInterval(()=> signal(signal()+1), interval); ac.signal.addEventListener("abort", ()=> setTimeout(()=> clearInterval(id), 2*interval)); setTimeout(()=> ac.abort(), 3*interval)

# Mnemonic