{"version":3,"file":"index.cjs","sources":["../src/index.tsx"],"sourcesContent":["import * as React from 'react'\r\nimport type ReactReconciler from 'react-reconciler'\r\n\r\n/**\r\n * An SSR-friendly useLayoutEffect.\r\n *\r\n * React currently throws a warning when using useLayoutEffect on the server.\r\n * To get around it, we can conditionally useEffect on the server (no-op) and\r\n * useLayoutEffect elsewhere.\r\n *\r\n * @see https://github.com/facebook/react/issues/14927\r\n */\r\nconst useIsomorphicLayoutEffect = /* @__PURE__ */ (() =>\r\n typeof window !== 'undefined' && (window.document?.createElement || window.navigator?.product === 'ReactNative'))()\r\n ? React.useLayoutEffect\r\n : React.useEffect\r\n\r\n/**\r\n * Represents a react-internal Fiber node.\r\n */\r\nexport type Fiber = Omit & { stateNode: T }\r\n\r\n/**\r\n * Represents a {@link Fiber} node selector for traversal.\r\n */\r\nexport type FiberSelector = (\r\n /** The current {@link Fiber} node. */\r\n node: Fiber,\r\n) => boolean | void\r\n\r\n/**\r\n * Traverses up or down a {@link Fiber}, return `true` to stop and select a node.\r\n */\r\nexport function traverseFiber(\r\n /** Input {@link Fiber} to traverse. */\r\n fiber: Fiber | undefined,\r\n /** Whether to ascend and walk up the tree. Will walk down if `false`. */\r\n ascending: boolean,\r\n /** A {@link Fiber} node selector, returns the first match when `true` is passed. */\r\n selector: FiberSelector,\r\n): Fiber | undefined {\r\n if (!fiber) return\r\n if (selector(fiber) === true) return fiber\r\n\r\n let child = ascending ? fiber.return : fiber.child\r\n while (child) {\r\n const match = traverseFiber(child, ascending, selector)\r\n if (match) return match\r\n\r\n child = ascending ? null : child.sibling\r\n }\r\n}\r\n\r\n// In development, React will warn about using contexts between renderers.\r\n// Hide the warning because its-fine fixes this issue\r\n// https://github.com/facebook/react/pull/12779\r\nfunction wrapContext(context: React.Context): React.Context {\r\n try {\r\n return Object.defineProperties(context, {\r\n _currentRenderer: {\r\n get() {\r\n return null\r\n },\r\n set() {},\r\n },\r\n _currentRenderer2: {\r\n get() {\r\n return null\r\n },\r\n set() {},\r\n },\r\n })\r\n } catch (_) {\r\n return context\r\n }\r\n}\r\n\r\nconst FiberContext = /* @__PURE__ */ wrapContext(/* @__PURE__ */ React.createContext(null!))\r\n\r\n/**\r\n * A react-internal {@link Fiber} provider. This component binds React children to the React Fiber tree. Call its-fine hooks within this.\r\n */\r\nexport class FiberProvider extends React.Component<{ children?: React.ReactNode }> {\r\n private _reactInternals!: Fiber\r\n\r\n render() {\r\n return {this.props.children}\r\n }\r\n}\r\n\r\n/**\r\n * Returns the current react-internal {@link Fiber}. This is an implementation detail of [react-reconciler](https://github.com/facebook/react/tree/main/packages/react-reconciler).\r\n */\r\nexport function useFiber(): Fiber | undefined {\r\n const root = React.useContext(FiberContext)\r\n if (root === null) throw new Error('its-fine: useFiber must be called within a !')\r\n\r\n const id = React.useId()\r\n const fiber = React.useMemo(() => {\r\n for (const maybeFiber of [root, root?.alternate]) {\r\n if (!maybeFiber) continue\r\n const fiber = traverseFiber(maybeFiber, false, (node) => {\r\n let state = node.memoizedState\r\n while (state) {\r\n if (state.memoizedState === id) return true\r\n state = state.next\r\n }\r\n })\r\n if (fiber) return fiber\r\n }\r\n }, [root, id])\r\n\r\n return fiber\r\n}\r\n\r\n/**\r\n * Represents a react-reconciler container instance.\r\n */\r\nexport interface ContainerInstance {\r\n containerInfo: T\r\n}\r\n\r\n/**\r\n * Returns the current react-reconciler container info passed to {@link ReactReconciler.Reconciler.createContainer}.\r\n *\r\n * In react-dom, a container will point to the root DOM element; in react-three-fiber, it will point to the root Zustand store.\r\n */\r\nexport function useContainer(): T | undefined {\r\n const fiber = useFiber()\r\n const root = React.useMemo(\r\n () => traverseFiber>(fiber, true, (node) => node.stateNode?.containerInfo != null),\r\n [fiber],\r\n )\r\n\r\n return root?.stateNode.containerInfo\r\n}\r\n\r\n/**\r\n * Returns the nearest react-reconciler child instance or the node created from {@link ReactReconciler.HostConfig.createInstance}.\r\n *\r\n * In react-dom, this would be a DOM element; in react-three-fiber this would be an instance descriptor.\r\n */\r\nexport function useNearestChild(\r\n /** An optional element type to filter to. */\r\n type?: keyof React.JSX.IntrinsicElements,\r\n): React.RefObject {\r\n const fiber = useFiber()\r\n const childRef = React.useRef(undefined)\r\n\r\n useIsomorphicLayoutEffect(() => {\r\n childRef.current = traverseFiber(\r\n fiber,\r\n false,\r\n (node) => typeof node.type === 'string' && (type === undefined || node.type === type),\r\n )?.stateNode\r\n }, [fiber])\r\n\r\n return childRef\r\n}\r\n\r\n/**\r\n * Returns the nearest react-reconciler parent instance or the node created from {@link ReactReconciler.HostConfig.createInstance}.\r\n *\r\n * In react-dom, this would be a DOM element; in react-three-fiber this would be an instance descriptor.\r\n */\r\nexport function useNearestParent(\r\n /** An optional element type to filter to. */\r\n type?: keyof React.JSX.IntrinsicElements,\r\n): React.RefObject {\r\n const fiber = useFiber()\r\n const parentRef = React.useRef(undefined)\r\n\r\n useIsomorphicLayoutEffect(() => {\r\n parentRef.current = traverseFiber(\r\n fiber,\r\n true,\r\n (node) => typeof node.type === 'string' && (type === undefined || node.type === type),\r\n )?.stateNode\r\n }, [fiber])\r\n\r\n return parentRef\r\n}\r\n\r\nexport type ContextMap = Map, any> & {\r\n get(context: React.Context): T | undefined\r\n}\r\n\r\nconst REACT_CONTEXT_TYPE = Symbol.for('react.context')\r\n\r\nconst isContext = (type: unknown): type is React.Context =>\r\n type !== null && typeof type === 'object' && '$$typeof' in type && type.$$typeof === REACT_CONTEXT_TYPE\r\n\r\n/**\r\n * Returns a map of all contexts and their values.\r\n */\r\nexport function useContextMap(): ContextMap {\r\n const fiber = useFiber()\r\n const [contextMap] = React.useState(() => new Map, any>())\r\n\r\n // Collect live context\r\n contextMap.clear()\r\n let node = fiber\r\n while (node) {\r\n const context = node.type\r\n if (isContext(context) && context !== FiberContext && !contextMap.has(context)) {\r\n contextMap.set(context, React.use(wrapContext(context)))\r\n }\r\n\r\n node = node.return!\r\n }\r\n\r\n return contextMap\r\n}\r\n\r\n/**\r\n * Represents a react-context bridge provider component.\r\n */\r\nexport type ContextBridge = React.FC>\r\n\r\n/**\r\n * React Context currently cannot be shared across [React renderers](https://reactjs.org/docs/codebase-overview.html#renderers) but explicitly forwarded between providers (see [react#17275](https://github.com/facebook/react/issues/17275)). This hook returns a {@link ContextBridge} of live context providers to pierce Context across renderers.\r\n *\r\n * Pass {@link ContextBridge} as a component to a secondary renderer to enable context-sharing within its children.\r\n */\r\nexport function useContextBridge(): ContextBridge {\r\n const contextMap = useContextMap()\r\n\r\n // Flatten context and their memoized values into a `ContextBridge` provider\r\n return React.useMemo(\r\n () =>\r\n Array.from(contextMap.keys()).reduce(\r\n (Prev, context) => (props) =>\r\n (\r\n \r\n \r\n \r\n ),\r\n (props) => ,\r\n ),\r\n [contextMap],\r\n )\r\n}\r\n"],"names":["useIsomorphicLayoutEffect","_a","_b","React","traverseFiber","fiber","ascending","selector","child","match","wrapContext","context","_","FiberContext","FiberProvider","useFiber","root","id","maybeFiber","node","state","useContainer","useNearestChild","type","childRef","useNearestParent","parentRef","REACT_CONTEXT_TYPE","isContext","useContextMap","contextMap","useContextBridge","Prev","props"],"mappings":"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"}