1
0
mirror of https://github.com/jaandrle/deka-dom-el synced 2025-07-01 04:12:14 +02:00

💥 rename signals to observables

This commit is contained in:
2023-11-24 20:41:04 +01:00
parent fc4037f3eb
commit 58b73dcbc7
44 changed files with 372 additions and 333 deletions

View File

@ -26,7 +26,7 @@ import { relative } from "node:path";
export function example({ src, language= "js", page_id }){
registerClientPart(page_id);
const content= s.cat(src).toString()
.replaceAll(/ from "deka-dom-el(\/signals)?";/g, ' from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js";');
.replaceAll(/ from "deka-dom-el(\/observables)?";/g, ' from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-observables.js";');
const id= "code-example-"+generateCodeId(src);
return el().append(
el(code, { id, content, language, className: example.name }),

View File

@ -1,5 +1,5 @@
import { el } from "deka-dom-el";
import { S } from "deka-dom-el/signals";
import { S } from "deka-dom-el/observables";
const clicks= S(0);
document.body.append(
el().append(

View File

@ -0,0 +1,16 @@
import { O } from "deka-dom-el/observables";
const observable= O(0);
// computation pattern
const double= O(()=> 2*observable());
const ac= new AbortController();
O.on(observable, v=> console.log("observable", v), { signal: ac.signal });
O.on(double, v=> console.log("double", v), { signal: ac.signal });
observable(observable()+1);
const interval= 5000;
const id= setInterval(()=> observable(observable()+1), interval);
ac.signal.addEventListener("abort",
()=> setTimeout(()=> clearInterval(id), 2*interval));
setTimeout(()=> ac.abort(), 3*interval)

View File

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

View File

@ -0,0 +1,8 @@
import { O } from "deka-dom-el/observables";
// α — `observable` represents a reactive value
const observable= O(0);
// β — just reacts on observable changes
O.on(observable, console.log);
// γ — just updates the value
observable(observable()+1);
setInterval(()=> observable(observable()+1), 5000);

View File

@ -1,16 +0,0 @@
import { S } from "deka-dom-el/signals";
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)

View File

@ -1,8 +0,0 @@
import { S } from "deka-dom-el/signals";
// α — `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);

View File

@ -23,10 +23,10 @@ export function page({ pkg, info }){
el("p").append(
"Next step is providing interactivity not only for our UI templates.",
" ",
"We introduce signals (", el("code", "S"), ") and how them incorporate to UI templates.",
"We introduce observables (", el("code", "O"), ") and how them incorporate to UI templates.",
),
el("p").append(
"Now we will clarify how the signals are incorporated into our templates with regard ",
"Now we will clarify how the observables are incorporated into our templates with regard ",
"to application performance. This is not the only reason the library uses ",
el("code", "scope"), "s. We will look at how they work in components represented ",
"in JavaScript by functions."

View File

@ -64,7 +64,7 @@ export function page({ pkg, info }){
"This is handy to concat conditional classes."
),
el("li").append(
"Use ", el("code", "classList"), " to toggle specific classes. This will be handy later when the reactivity via signals is beeing introduced.",
"Use ", el("code", "classList"), " to toggle specific classes. This will be handy later when the reactivity via observables is beeing introduced.",
),
el("li").append(
"The ", el("code", "assign"), " also accepts the ", el("code", "undefined"), " as a value for any property to remove it from the element declaratively. ",

View File

@ -12,24 +12,24 @@ const fileURL= url=> new URL(url, import.meta.url);
export function page({ pkg, info }){
const page_id= info.id;
return el(simplePage, { info, pkg }).append(
el("h2", "Using signals to manage reactivity"),
el("h2", "Using observables to manage reactivity"),
el("p").append(
"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.",
" observables may be a viable approach.",
),
el(code, { src: fileURL("./components/examples/signals/intro.js"), page_id }),
el(code, { src: fileURL("./components/examples/observables/intro.js"), page_id }),
el(h3, "Introducing signals"),
el(h3, "Introducing observables"),
el("p").append(
"Using signals, we split program logic into the three parts.",
"Using observables, 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."
" to the observable value changes. Similarly, in a remaining part (γ), we",
" can update the observable value."
),
el(example, { src: fileURL("./components/examples/signals/signals.js"), page_id }),
el(example, { src: fileURL("./components/examples/observables/observables.js"), page_id }),
el("p").append(
"All this is just an example of ",
el("a", { textContent: "Event-driven programming", href: "https://en.wikipedia.org/wiki/Event-driven_programming", title: "Wikipedia: Event-driven programming" }),
@ -40,35 +40,35 @@ export function page({ pkg, info }){
" to the same reactive entity."
),
el("p").append(
"Signals are implemented in the library as functions. To see current value",
" of signal, just call it without any arguments ", el("code", "console.log(signal())"), ".",
" To update the signal value, pass any argument ", el("code", "signal('a new value')"), ".",
" For listenning the signal value changes, use ", el("code", "S.on(signal, console.log)"), "."
"Observables are implemented in the library as functions. To see current value",
" of observable, just call it without any arguments ", el("code", "console.log(observable())"), ".",
" To update the observable value, pass any argument ", el("code", "observable('a new value')"), ".",
" For listenning the observable value changes, use ", el("code", "O.on(observable, console.log)"), "."
),
el("p").append(
"Similarly to the ", el("code", "on"), " function to register DOM events listener.",
" You can use ", el("code", "AbortController"), "/", el("code", "AbortSignal"), " to",
" ", el("em", "off"), "/stop listenning. For representing “live” piece of code computation pattern:"
),
el(example, { src: fileURL("./components/examples/signals/computations-abort.js"), page_id }),
el(example, { src: fileURL("./components/examples/observables/computations-abort.js"), page_id }),
el(mnemonicUl).append(
el("li").append(
el("code", "S(<value>)"), " — signal: reactive value",
el("code", "O(<value>)"), " — observable: reactive value",
),
el("li").append(
el("code", "S(()=> <computation>)"), " — signal: reactive value dependent on calculation using other signals",
el("code", "O(()=> <computation>)"), " — observable: reactive value dependent on calculation using other observables",
),
el("li").append(
el("code", "S.on(<signal>, <listener>[, <options>])"), " — listen to the signal value changes",
el("code", "O.on(<observable>, <listener>[, <options>])"), " — listen to the observable value changes",
),
el("li").append(
el("code", "S.clear(...<signals>)"), " — off and clear signals",
el("code", "O.clear(...<observables>)"), " — off and clear observables",
),
el("li").append(
el("code", "S(<value>, <actions>)"), " — signal: pattern to create complex reactive objects/arrays",
el("code", "O(<value>, <actions>)"), " — observable: pattern to create complex reactive objects/arrays",
),
el("li").append(
el("code", "S.action(<signal>, <action-name>, ...<action-arguments>)"), " — invoke an action for given signal"
el("code", "O.action(<observable>, <action-name>, ...<action-arguments>)"), " — invoke an action for given observable"
)
),
);

View File

@ -6,7 +6,7 @@ export const pages= [
{ id: "index", href: "./", title: "Introduction", description: "Introducing a library." },
{ id: "p02-elements", href: "p02-elements", title: "Elements", description: "Basic concepts of elements modifications and creations." },
{ id: "p03-events", href: "p03-events", title: "Events and Addons", description: "Using not only events in UI declaratively." },
{ id: "p04-signals", href: "p04-signals", title: "Signals and reactivity", description: "Handling reactivity in UI via signals." },
{ id: "p04-observables", href: "p04-observables", title: "Observables and reactivity", description: "Handling reactivity in UI via observables." },
];
/**
* @typedef registerClientFile