alistair
Version:
69 lines (66 loc) • 1.97 kB
JavaScript
import { useEvent } from '../chunk-AKIQJILB.js';
import { useSyncExternalStore, useEffect, useCallback } from 'react';
// Copyright 2026 Alistair Smith https://github.com/alii/alistair
function atom(initialValue) {
let state = initialValue === undefined ? { initialized: false } : { initialized: true, value: initialValue };
const subscriptions = /* @__PURE__ */ new Set();
const get = () => {
if (!state.initialized) {
throw new Error("Cannot read an atom that is uninitialized");
}
return state.value;
};
const notify = (value) => {
for (const notify2 of subscriptions) {
notify2(value);
}
};
const set = (next) => {
const current = get();
const resolved = next instanceof Function ? next(current) : next;
if (Object.is(resolved, current)) {
return;
}
state = { initialized: true, value: resolved };
notify(resolved);
};
return {
get,
set,
subscribe: (callback) => {
subscriptions.add(callback);
return () => {
subscriptions.delete(callback);
};
}
};
}
function writable(init, toAction) {
const a = atom(init);
return {
get: a.get,
set: (next) => {
a.set(toAction(next));
},
subscribe: a.subscribe
};
}
function useAtomValue(atom2) {
return useSyncExternalStore(atom2.subscribe, atom2.get, atom2.get);
}
function useAtom(atom2) {
return [useAtomValue(atom2), atom2.set];
}
function useAtomDidChange(atom2, callback) {
const stable = useEvent(callback);
useEffect(() => atom2.subscribe((value) => stable(value)), [atom2]);
}
function useSelectAtomValue(atom2, selector, dependencies = []) {
const subscribe = useCallback(
(notify) => atom2.subscribe(notify),
[atom2, ...dependencies]
);
const getSnapshot = () => selector(atom2.get());
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
}
export { atom, useAtom, useAtomDidChange, useAtomValue, useSelectAtomValue, writable };