Overview

lsStore and ssStore are shared AtomType<Record | null> bags on utils (MatesUtils). Both persist under the key mates_storage — local vs session respectively.

lsStore hydrates on create, writes JSON on every set/update, and syncs from other tabs via the storage event. ssStore is tab-scoped session storage (no cross-tab sync).

Both start as null on first visit. Call .set({…}) before .update() — update is a no-op while null. Values must be JSON-serialisable.

lsStore vs ssStore

API
Backend
Sync
lsStore localStorage Survives reloads; cross-tab via storage event.
ssStore sessionStorage Tab session only; no cross-tab sync.

lsStore — persistent clicks

set() seeds the bag; update() patches in place. Reload the preview — clicks survive in localStorage (mates_storage).

import { html, useUtils, renderApp } from 'mates';

const App = () => {
const { lsStore } = useUtils();

const ensure = () => {
if (lsStore() == null) lsStore.set({ clicks: 0, label: 'demo' });
};
ensure();

return () => html`
<div class="m-col m-gap">
<p class="muted">lsStore clicks: <strong>${lsStore()?.clicks ?? 0}</strong></p>
<p class="muted m-t-5">label=${lsStore()?.label ?? '—'}</p>
<div class="m-flex m-items-center m-justify-center m-gap-sm">
<button class="btn-primary" @click=${() => {
ensure();
lsStore.update((d) => { d.clicks = (d.clicks ?? 0) + 1; });
}}>+1 persist</button>
<button class="btn-ghost" @click=${() => lsStore.set(null)}>clear</button>
</div>
</div>
`;
};
renderApp(App, document.getElementById('app'));

ssStore — session draft

Same API as lsStore, backed by sessionStorage. Useful for ephemeral drafts that should not cross tabs.

import { html, useUtils, renderApp } from 'mates';

const App = () => {
const { ssStore } = useUtils();

if (ssStore() == null) ssStore.set({ note: '' });

return () => html`
<div class="m-col m-gap">
<input
.value=${ssStore()?.note ?? ''}
@input=${(e) => {
if (ssStore() == null) ssStore.set({ note: e.target.value });
else ssStore.update((d) => { d.note = e.target.value; });
}}
placeholder="session draft…"
/>
<p class="muted m-t-5">ssStore (tab session only)</p>
</div>
`;
};
renderApp(App, document.getElementById('app'));