@westacks/vortex
Version:
Server-based routing for SPAs
71 lines (70 loc) • 1.83 kB
JavaScript
;
function isEqual(x, y) {
const ok = Object.keys, tx = typeof x, ty = typeof y;
return x && y && tx === "object" && tx === ty ? ok(x).length === ok(y).length && ok(x).every((key) => isEqual(x[key], y[key])) : x === y;
}
let observer = null;
function signal(value = void 0, equals = (a, b) => a === b) {
let state = value;
const subscribers = /* @__PURE__ */ new Set();
function unlink(dependency) {
subscribers.delete(dependency);
}
function get() {
if (observer && !subscribers.has(observer)) {
subscribers.add(observer);
observer.link(unlink);
}
return state;
}
function set(value2, force = false) {
const next = value2 instanceof Function ? value2(state) : value2;
if (!force && equals(state, next)) return;
state = next;
for (const subscriber of [...subscribers]) {
subscriber.notify();
}
}
return [get, set];
}
function effect(fn) {
let cleaner;
const subscribers = /* @__PURE__ */ new Set();
const instance = { notify, link };
function notify() {
dispose();
observer = instance;
try {
cleaner = fn();
} catch (e) {
console.error(e);
}
observer = null;
}
function link(unlink) {
subscribers.add(unlink);
}
async function dispose() {
for (const unlink of subscribers) {
unlink(instance);
}
subscribers.clear();
const flush = await cleaner;
if (flush instanceof Function) {
flush();
}
cleaner = void 0;
}
notify();
return dispose;
}
const page = signal(void 0, isEqual);
const getPage = page[0];
const setPage = page[1];
const subscribe = (fn) => effect(() => fn(getPage()));
exports.effect = effect;
exports.getPage = getPage;
exports.isEqual = isEqual;
exports.setPage = setPage;
exports.signal = signal;
exports.subscribe = subscribe;