"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var use_context_selector_exports = {};
__export(use_context_selector_exports, {
  createContext: () => createContext,
  useContext: () => useContext,
  useContextSelector: () => useContextSelector,
  useContextSelectorWithValue: () => useContextSelectorWithValue
});
module.exports = __toCommonJS(use_context_selector_exports);
var import_react = require("react");
const CONTEXT_VALUE = Symbol();
const ORIGINAL_PROVIDER = Symbol();
const isSSR = typeof window === "undefined";
const useIsomorphicLayoutEffect = isSSR ? import_react.useEffect : import_react.useLayoutEffect;
const runWithNormalPriority = (thunk) => thunk();
const createProvider = (ProviderOrig) => ({ value, children, onSelectorContextValue }) => {
  const valueRef = (0, import_react.useRef)(value);
  const versionRef = (0, import_react.useRef)(0);
  const contextValue = (0, import_react.useRef)();
  if (!contextValue.current) {
    const listeners = /* @__PURE__ */ new Set();
    const update = (fn) => {
      versionRef.current += 1;
      listeners.forEach((listener) => listener([versionRef.current]));
      fn();
    };
    contextValue.current = {
      [CONTEXT_VALUE]: {
        /* "v"alue     */
        v: valueRef,
        /* versio"n"   */
        n: versionRef,
        /* "l"isteners */
        l: listeners,
        /* "u"pdate    */
        u: update
      }
    };
    onSelectorContextValue?.(contextValue.current);
  }
  useIsomorphicLayoutEffect(() => {
    valueRef.current = value;
    versionRef.current += 1;
    runWithNormalPriority(() => {
      contextValue.current[CONTEXT_VALUE].l.forEach((listener) => {
        listener([versionRef.current, value]);
      });
    });
  }, [value]);
  return (0, import_react.createElement)(ProviderOrig, { value: contextValue.current }, children);
};
const identity = (x) => x;
function createContext(defaultValue) {
  const context = (0, import_react.createContext)({
    [CONTEXT_VALUE]: {
      /* "v"alue     */
      v: { current: defaultValue },
      /* versio"n"   */
      n: { current: -1 },
      /* "l"isteners */
      l: /* @__PURE__ */ new Set(),
      /* "u"pdate    */
      u: (f) => f()
    }
  });
  context[ORIGINAL_PROVIDER] = context.Provider;
  context.Provider = createProvider(context.Provider);
  delete context.Consumer;
  return context;
}
function useContextSelector(context, selector, equalityFn, trackString) {
  const contextValue = (0, import_react.useContext)(
    context
  );
  return useContextSelectorWithValue(contextValue, selector, equalityFn, trackString);
}
function useContextSelectorWithValue(selectorContextValue, selector, equalityFn, trackString) {
  const contextValue = selectorContextValue[CONTEXT_VALUE];
  if (typeof process === "object" && false) {
    if (!contextValue) {
      throw new Error("useContextSelector requires special context");
    }
  }
  const {
    /* "v"alue     */
    v: { current: value },
    /* versio"n"   */
    n: { current: version },
    /* "l"isteners */
    l: listeners
  } = contextValue;
  const selected = selector(value);
  const [state, dispatch] = (0, import_react.useReducer)(
    (prev, next) => {
      if (trackString) {
        console.log(trackString, "re-render");
      }
      if (!next) {
        return [value, selected];
      }
      if (next[0] <= version) {
        if (equalityFn(prev[1], selected)) {
          return prev;
        }
        return [value, selected];
      }
      try {
        if (next.length === 2) {
          if (Object.is(prev[0], next[1])) {
            return prev;
          }
          const nextSelected = selector(next[1]);
          if (equalityFn(prev[1], nextSelected)) {
            return prev;
          }
          return [next[1], nextSelected];
        }
      } catch {
      }
      return [...prev];
    },
    [value, selected]
  );
  if (!equalityFn(state[1], selected)) {
    dispatch();
  }
  useIsomorphicLayoutEffect(() => {
    listeners.add(dispatch);
    return () => {
      listeners.delete(dispatch);
    };
  }, [listeners]);
  return state[1];
}
function useContext(context) {
  return useContextSelector(context, identity, Object.is);
}
//# sourceMappingURL=use-context-selector.js.map
