1
0
mirror of https://github.com/jaandrle/deka-dom-el synced 2025-07-17 02:16:29 +02:00

Replace “observable” term with “signal” (#19)

*  refact docs

to make editing (now renaming observables to signal) easier

*   use signal(s) term isntead of observable(s)

*  🔤 version + typo

* 🐛 customElement example (0→S)

* 📺 version in package-lock.json
This commit is contained in:
2024-05-22 21:43:49 +02:00
committed by GitHub
parent 4014e79740
commit cd62782c7b
65 changed files with 1426 additions and 978 deletions

View File

@ -14,7 +14,7 @@ ${host}{
}
`;
const dde_content= s.cat(new URL("../../dist/esm-with-observables.js", import.meta.url)).toString();
const dde_content= s.cat(new URL("../../dist/esm-with-signals.js", import.meta.url)).toString();
import { el } from "deka-dom-el";
import { code } from "./code.html.js";
@ -29,7 +29,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(\/observables)?";/g, ' from "./esm-with-observables.js";');
.replaceAll(/ from "deka-dom-el(\/signals)?";/g, ' from "./esm-with-signals.js";');
const id= "code-example-"+generateCodeId(src);
return el().append(
el(code, { id, content, language, className: example.name }),
@ -38,7 +38,7 @@ export function example({ src, language= "js", page_id }){
}
function elCode({ id, content, extension: name }){
const options= JSON.stringify({
files: [{ name, content }, { name: "esm-with-observables.js", content: dde_content }],
files: [{ name, content }, { name: "esm-with-signals.js", content: dde_content }],
toolbar: false
});
return el("script", `Flems(document.getElementById("${id}"), JSON.parse(${JSON.stringify(options)}));`);

View File

@ -1,12 +1,12 @@
// use NPM or for example https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-observables.js
// use NPM or for example https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js
import {
customElementRender,
customElementWithDDE,
observedAttributes,
} from "deka-dom-el";
/** @type {ddePublicElementTagNameMap} */
import { O } from "deka-dom-el/observables";
O.observedAttributes;
import { S } from "deka-dom-el/signals";
S.observedAttributes;
// “internal” utils
import { lifecyclesToEvents } from "deka-dom-el";

View File

@ -1,9 +1,9 @@
import { el } from "deka-dom-el";
import { O } from "deka-dom-el/observables";
const clicks= O(0);
import { S } from "deka-dom-el/signals";
const clicks= S(0);
document.body.append(
el().append(
el("p", O(()=>
el("p", S(()=>
"Hello World "+"🎉".repeat(clicks())
)),
el("button", {

View File

@ -1,16 +0,0 @@
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= 5 * 1000;
const id= setInterval(()=> observable(observable()+1), interval);
ac.signal.addEventListener("abort",
()=> setTimeout(()=> clearInterval(id), 2*interval));
setTimeout(()=> ac.abort(), 3*interval)

View File

@ -1,6 +0,0 @@
// use NPM or for example https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-observables.js
import { O, observable } from "deka-dom-el/observables";
O===observable
/** @type {ddeObservable} */
/** @type {ddeAction} */
/** @type {ddeActions} */

View File

@ -1,12 +0,0 @@
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
const update= ()=> observable(observable()+1);
update();
const interval= 5*1000;
setTimeout(clearInterval, 10*interval,
setInterval(update, interval));

View File

@ -7,9 +7,9 @@ document.body.append(
type: "button"
})
);
import { O } from "deka-dom-el/observables";
import { S } from "deka-dom-el/signals";
function component(){
const textContent= O("Click to change text.");
const textContent= S("Click to change text.");
const onclickChange= on("click", function redispatch(){
textContent("Text changed! "+(new Date()).toString())

View File

@ -1,10 +1,10 @@
/* PSEUDO-CODE!!! */
import { el } from "deka-dom-el";
import { O } from "deka-dom-el/observables";
import { S } from "deka-dom-el/signals";
function component(){
/* prepare changeable data */
const dataA= O("data");
const dataB= O("data");
const dataA= S("data");
const dataB= S("data");
/* define data flow (can be asynchronous) */
fetchAPI().then(data_new=> dataA(data_new));
setTimeout(()=> dataB("DATA"));
@ -17,17 +17,17 @@ function component(){
}),
el("ul").append(
/* declarative element(s) */
O.el(dataA, data=> data.map(d=> el("li", d)))
S.el(dataA, data=> data.map(d=> el("li", d)))
),
el("ul").append(
/* declarative component(s) */
O.el(dataA, data=> data.map(d=> el(subcomponent, d)))
S.el(dataA, data=> data.map(d=> el(subcomponent, d)))
)
);
}
function subcomponent({ id }){
/* prepare changeable data */
const textContent= O("…");
const textContent= S("…");
/* define data flow (can be asynchronous) */
fetchAPI(id).then(text=> textContent(text));
/* declarative UI */

View File

@ -1,3 +1,3 @@
// use NPM or for example https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-observables.js
// use NPM or for example https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js
import { scope, el } from "deka-dom-el";
/** @type {ddeElementAddon} */

View File

@ -1,14 +1,14 @@
import { O } from "deka-dom-el/observables";
const observable= O(0, {
import { S } from "deka-dom-el/signals";
const signal= S(0, {
increaseOnlyOdd(add){
console.info(add);
if(add%2 === 0) return this.stopPropagation();
this.value+= add;
}
});
O.on(observable, console.log);
S.on(signal, console.log);
const oninterval= ()=>
O.action(observable, "increaseOnlyOdd", Math.floor(Math.random()*100));
S.action(signal, "increaseOnlyOdd", Math.floor(Math.random()*100));
const interval= 5*1000;
setTimeout(

View File

@ -1,14 +1,14 @@
import { O } from "deka-dom-el/observables";
const todos= O([], {
import { S } from "deka-dom-el/signals";
const todos= S([], {
push(item){
this.value.push(O(item));
this.value.push(S(item));
},
pop(){
const removed= this.value.pop();
if(removed) O.clear(removed);
if(removed) S.clear(removed);
},
[O.symbols.onclear](){ // this covers `O.clear(todos)`
O.clear(...this.value);
[S.symbols.onclear](){ // this covers `O.clear(todos)`
S.clear(...this.value);
}
});
@ -19,7 +19,7 @@ const onsubmit= on("submit", function(event){
const data= new FormData(this);
switch (data.get("op")){
case "A"/*dd*/:
O.action(todos, "push", data.get("todo"));
S.action(todos, "push", data.get("todo"));
break;
case "E"/*dit*/: {
const last= todos().at(-1);
@ -28,13 +28,13 @@ const onsubmit= on("submit", function(event){
break;
}
case "R"/*emove*/:
O.action(todos, "pop");
S.action(todos, "pop");
break;
}
});
document.body.append(
el("ul").append(
O.el(todos, todos=>
S.el(todos, todos=>
todos.map(textContent=> el("li", textContent)))
),
el("form", null, onsubmit).append(

View File

@ -0,0 +1,16 @@
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= 5 * 1000;
const id= setInterval(()=> signal(signal()+1), interval);
ac.signal.addEventListener("abort",
()=> setTimeout(()=> clearInterval(id), 2*interval));
setTimeout(()=> ac.abort(), 3*interval)

View File

@ -1,10 +1,10 @@
import { O } from "deka-dom-el/observables";
const count= O(0);
import { S } from "deka-dom-el/signals";
const count= S(0);
import { el } from "deka-dom-el";
document.body.append(
el("p", O(()=> "Currently: "+count())),
el("p", { classList: { red: O(()=> count()%2) }, dataset: { count }, textContent: "Attributes example" })
el("p", S(()=> "Currently: "+count())),
el("p", { classList: { red: S(()=> count()%2) }, dataset: { count }, textContent: "Attributes example" })
);
document.head.append(
el("style", ".red { color: red; }")

View File

@ -1,26 +1,26 @@
import { O } from "deka-dom-el/observables";
const count= O(0, {
import { S } from "deka-dom-el/signals";
const count= S(0, {
add(){ this.value= this.value + Math.round(Math.random()*10); }
});
const numbers= O([ count() ], {
const numbers= S([ count() ], {
push(next){ this.value.push(next); }
});
import { el } from "deka-dom-el";
document.body.append(
O.el(count, count=> count%2
S.el(count, count=> count%2
? el("p", "Last number is odd.")
: el()
),
el("p", "Lucky numbers:"),
el("ul").append(
O.el(numbers, numbers=> numbers.toReversed()
S.el(numbers, numbers=> numbers.toReversed()
.map(n=> el("li", n)))
)
);
const interval= 5*1000;
setTimeout(clearInterval, 10*interval, setInterval(function(){
O.action(count, "add");
O.action(numbers, "push", count());
S.action(count, "add");
S.action(numbers, "push", count());
}, interval));

View File

@ -0,0 +1,6 @@
// use NPM or for example https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js
import { S, signal } from "deka-dom-el/signals";
S===signal
/** @type {ddeSignal} */
/** @type {ddeAction} */
/** @type {ddeActions} */

View File

@ -0,0 +1,12 @@
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
const update= ()=> signal(signal()+1);
update();
const interval= 5*1000;
setTimeout(clearInterval, 10*interval,
setInterval(update, interval));

View File

@ -13,7 +13,7 @@ export function mnemonic(){
el("code", "observedAttributes(<custom-element>)"), " — returns record of observed attributes (keys uses camelCase)",
),
el("li").append(
el("code", "O.observedAttributes(<custom-element>)"), " — returns record of observed attributes (keys uses camelCase and values are observables)",
el("code", "S.observedAttributes(<custom-element>)"), " — returns record of observed attributes (keys uses camelCase and values are signals)",
),
el("li").append(
el("code", "lifecyclesToEvents(<class-declaration>)"), " — convert lifecycle methods to events, can be also used as decorator",

View File

@ -1,28 +0,0 @@
import { el } from "deka-dom-el";
import { mnemonicUl } from "../mnemonicUl.html.js";
export function mnemonic(){
return mnemonicUl().append(
el("li").append(
el("code", "O(<value>)"), " — observable: reactive value",
),
el("li").append(
el("code", "O(()=> <computation>)"), " — read-only observable: reactive value dependent on calculation using other observables",
),
el("li").append(
el("code", "O.on(<observable>, <listener>[, <options>])"), " — listen to the observable value changes",
),
el("li").append(
el("code", "O.clear(...<observables>)"), " — off and clear observables",
),
el("li").append(
el("code", "O(<value>, <actions>)"), " — observable: pattern to create complex reactive objects/arrays",
),
el("li").append(
el("code", "O.action(<observable>, <action-name>, ...<action-arguments>)"), " — invoke an action for given observable"
),
el("li").append(
el("code", "O.el(<observable>, <function-returning-dom>)"), " — render partial dom structure (template) based on the current observable value",
)
);
}

View File

@ -0,0 +1,28 @@
import { el } from "deka-dom-el";
import { mnemonicUl } from "../mnemonicUl.html.js";
export function mnemonic(){
return mnemonicUl().append(
el("li").append(
el("code", "S(<value>)"), " — signal: reactive value",
),
el("li").append(
el("code", "S(()=> <computation>)"), " — read-only signal: reactive value dependent on calculation using other signals",
),
el("li").append(
el("code", "S.on(<signal>, <listener>[, <options>])"), " — listen to the signal value changes",
),
el("li").append(
el("code", "S.clear(...<signals>)"), " — off and clear signals",
),
el("li").append(
el("code", "S(<value>, <actions>)"), " — signal: 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("li").append(
el("code", "S.el(<signal>, <function-returning-dom>)"), " — render partial dom structure (template) based on the current signal value",
)
);
}