Show HN: Mador – Make any DOM reactive with a tiny 80-line Proxy state tuple
github.com
github.com
let counter = proxy({ count: 0 });
bind('.counter', (el) => el.textContent = counter.count);
counter.count++; // Queues DOM update
Also,> Mador is distributed as an ES module.
This means it cannot be used on a page opened from disk, and the user needs to set up a HTTP server which is time-consuming and distracting. And you cannot distribute an app as as HTML file.
<script type="module">
console.log('Hello World!')
export const a = 5
</script>
Inline module scripts work fine in HTML.
You can't import this, but if you'd anyway need to do some "building" (at least doing some string concatenation as a build script) to get any JS baked into the HTML, so why not just concat the library and your own code to one module script in the HTML.
Works fine.I think it's good that folks are starting to end distributing prebuilt code in every possible format that somebody could ask for. Waste of disk space for most people.
ESM is how it's done now. If you don't like it, build it yourself to some other format.
Good learning experience but a very weird presentation.
preact/signals-core is great, but since HTML elements have no way to subscribe to signals, you have to handle that yourself:
import { signal, effect } from "@preact/signals-core";
const $ = (s) => document.querySelector(s);
const counter = signal(0);
effect(() => {
$('.counter').textContent = counter.value;
});
$('.increment').addEventListener('click', () => {
counter.value += 1;
});
vs mador:
import mador from "https://cdn.jsdelivr.net/npm/@marsbos/mador@latest/dist/mador.js";
const $ = (s) => document.querySelector(s);
const [read, write] = mador({
count: 0,
});
read(".counter", (el, count) => {
el.textContent = count;
},
(state) => state.count,
);
$('.increment').addEventListener('click', () => {
write((state) => { state.count++; });
});
Anyways, I love projects like these that try to make working with the web easier with minimal tools.Honestly, this seems pretty nifty. Most projects I'd do today would likely have more value in Vue as a whole, and it's nice to see these kinds of things exposed and standalone bits
[1] https://github.com/vuejs/core/tree/main/packages/reactivity/...
So while Vue is not gatekeeping their reactive primitive library, they aren't exactly advertising it like Preact in a way that the average library author (like Mador's author) might even be aware of it.
Also as someone who has built React applications for more than 7+ years, I'm also still not sure what React's reactive primitive package is. Googling or asking ChatGPT has turned up nothing.
```js import mador from "mador"; const [read, write] = mador({ count: 1 }); read(".counter", ctx => ctx.el.textContent = ctx.count); write(".increment", "click", ctx => ctx.count++); write(ctx => ctx.count = 0); ```
## Read
Dependencies are detected automatically when the read function is run during initiation.
```js read(".counter", ctx => ctx.el.textContent = `Count: ${ctx.count}`); ```
## Write
Immediate:
```js write(ctx => ctx.count++); ```
Event-triggered:
```js write(".increment", "click", ctx => ctx.count++); ```
Event writes expose `ctx.el` and `ctx.event`.
It’s a very smart idea though, I like it.
Unsure why this comment from the author was flagged/dead but it certainly doesn’t seem to run afoul of HN guidelines.
window.state = new Proxy({}, {
set(target, key, value) {
target[key] = value
document.querySelectorAll(`[data="${key}"]`)
.forEach(el => el.render?.())
return true
}
})
handles reactivity.. https://github.com/digplan/vanilla-lightImho, custom elements are great, but very limited in a way that they almost always require knowledge of the domain.
Perhaps I can figure out a way to combine mador.js & custom elements.