Overview

molecule is a small singleton helper for nested “bags” that mix atoms, plain data, and methods (forms, stores, scope instances). It walks objects and arrays, visits every Mates atom, and skips non-atoms.

every / some mirror Array.prototype (including short-circuit). each runs a visitor on every atom. The walker does not recurse into atom values, and it guards against circular references.

molecule vs manual walks

Approach
Tracks atoms?
Prefer when
molecule.* Yes Deep bags with mixed fields — forms, stores, scopes.
Hand-rolled Object.keys Easy to miss nest Only for flat, known shapes.
effect on known deps Reactive When you already list the atoms you care about.

every + some on a form bag

Nested score atom is included. every/some short-circuit like Array methods.

import { html, atom, molecule, renderApp } from 'mates';

const App = () => {
const form = {
name: atom('Ada'),
email: atom(''),
nested: { score: atom(10) },
};

const allFilled = () =>
molecule.every(form, (a) => {
const v = a();
return v !== '' && v != null;
});

const anyEmpty = () =>
molecule.some(form, (a) => a() === '');

return () => html`
<div class="m-col m-gap">
<input .value=${form.name()} @input=${(e) => form.name.set(e.target.value)}
placeholder="name" />
<input .value=${form.email()} @input=${(e) => form.email.set(e.target.value)}
placeholder="email" />
<p class="muted m-t-5">
every filled: ${allFilled()} · some empty: ${anyEmpty()}
</p>
<p class="muted">score=${form.nested.score()} (nested atom is walked)</p>
</div>
`;
};
renderApp(App, document.getElementById('app'));

each — bump every atom

Visitor mutates each atom found in the nested bag.

import { html, atom, molecule, renderApp } from 'mates';

const App = () => {
const bag = {
a: atom(1),
b: atom(2),
nest: { c: atom(3) },
};
const log = atom('');

const bumpAll = () => {
molecule.each(bag, (a) => a.set((n) => n + 1));
log.set('bumped every atom');
};

return () => html`
<div class="m-col m-gap">
<p style="font-size:1.25rem">
a=${bag.a()} b=${bag.b()} c=${bag.nest.c()}
</p>
<button class="btn-primary" @click=${bumpAll}>each → incr</button>
<p class="muted m-t-5">${log()}</p>
</div>
`;
};
renderApp(App, document.getElementById('app'));