Show HN: Mador – Make any DOM reactive with a tiny 80-line Proxy state tuple
Posted by bosmarcel 1 day ago
Comments
Comment by codedokode 1 day ago
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.
Comment by inbx0 1 day ago
<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.
Comment by pwdisswordfishq 1 day ago
Comment by bedroom_jabroni 1 day ago
Comment by nxobject 1 day ago
Comment by royal_ts 1 day ago
Comment by bosmarcel 1 day ago
Comment by bedroom_jabroni 1 day ago
Good learning experience but a very weird presentation.
Comment by kevinfiol 1 day ago
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.Comment by bedroom_jabroni 1 day ago
Comment by kevinfiol 19 hours ago
Comment by phatskat 13 hours ago
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/...
Comment by bosmarcel 1 day ago
Comment by bosmarcel 1 day ago
Comment by bedroom_jabroni 1 day ago
Comment by afavour 1 day ago
Comment by moostee 1 day ago
```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`.
Comment by bosmarcel 1 day ago
Comment by afavour 1 day ago
It’s a very smart idea though, I like it.
Comment by codedokode 1 day ago
Comment by abosalehworld 1 day ago
Comment by PoignardAzur 1 day ago
Comment by bosmarcel 1 day ago
Comment by DylanMerigaud 1 day ago
Comment by bosmarcel 1 day ago
Comment by ahmedhossamdev 1 day ago
Comment by bosmarcel 1 day ago
Comment by carlailab2025 21 hours ago
Comment by bosmarcel 1 day ago
Comment by hamburglar 1 day ago
Unsure why this comment from the author was flagged/dead but it certainly doesn’t seem to run afoul of HN guidelines.
Comment by favori995749721 1 day ago
Comment by boldaxolotl 1 day ago
Comment by dpweb 1 day ago
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-lightComment by bosmarcel 1 day ago
Imho, 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.