alistair
Version:
106 lines (103 loc) • 2.9 kB
JavaScript
import { useLazyRef } from '../chunk-7QJBAV5Y.js';
import { useEvent } from '../chunk-AKIQJILB.js';
import * as react from 'react';
import { jsx } from 'react/jsx-runtime';
// Copyright 2026 Alistair Smith https://github.com/alii/alistair
function createStrictContext(defaultValue = null) {
const context = react.createContext(defaultValue);
function Provider({ value, children }) {
return /* @__PURE__ */ jsx(context.Provider, { value, children });
}
function useContext2() {
const value = react.useContext(context);
if (value === null) {
throw new Error("useContext() must be used within a <Provider />");
}
return value;
}
return {
useContext: useContext2,
Provider
};
}
function createStoreContext() {
const context = createStrictContext();
const identity = (value) => value;
function Provider({ value, children }) {
const store = useLazyRef(() => {
let val = value;
const listeners = /* @__PURE__ */ new Set();
const notify = () => {
for (const listener of listeners) {
listener();
}
};
const set = (next) => {
val = next;
notify();
};
const subscribe = (listener) => {
listeners.add(listener);
return () => {
listeners.delete(listener);
};
};
const get = () => val;
return {
subscribe,
set,
get
};
});
react.useEffect(() => {
store.current.set(value);
}, [value]);
return /* @__PURE__ */ jsx(context.Provider, { value: store.current, children });
}
function useSelectContext(selector = identity, dependencies = []) {
const store = context.useContext();
const cache = react.useMemo(
() => ({ current: null }),
dependencies
);
const subscribe = react.useCallback(
(listener) => store.subscribe(listener),
dependencies
);
const getSnapshot = () => {
const state = store.get();
if (cache.current && cache.current[0] === state) {
return cache.current[1];
}
const next = selector(state);
cache.current = [state, next];
return next;
};
const slice = react.useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
react.useDebugValue(slice);
return slice;
}
return {
Provider,
useSelectContext
};
}
function useCacheSelector() {
const cache = useLazyRef(() => /* @__PURE__ */ new WeakMap());
return (compute) => {
const stable = useEvent(compute);
return react.useCallback(
(prev) => {
const cached = cache.current.get(prev);
if (cached !== undefined) {
return cached;
}
const next = stable(prev);
cache.current.set(prev, next);
return next;
},
[stable]
);
};
}
export { createStoreContext, createStrictContext, useCacheSelector };