UNPKG

alistair

Version:
106 lines (103 loc) 2.9 kB
import { useLazyRef } from '../chunk-J54L5FET.js'; import { useEvent } from '../chunk-UCYEPI4U.js'; import * as react from 'react'; import { jsx } from 'react/jsx-runtime'; // Copyright 2025 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 };