fix(mobile): resolve user avatars, chat alignment, timestamp formatting, and payslips API

This commit is contained in:
2026-08-10 17:55:14 +08:00
parent 6fe1fe125e
commit 9597cbf99a
1468 changed files with 172818 additions and 65664 deletions

7
node_modules/bippy/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,7 @@
Copyright 2024 Aiden Bai
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

655
node_modules/bippy/README.md generated vendored Normal file
View File

@@ -0,0 +1,655 @@
> [!WARNING]
> ⚠️⚠️⚠️ **this project may break production apps and cause unexpected behavior** ⚠️⚠️⚠️
>
> this project uses react internals, which can change at any time. we don't recommend depending on internals unless you really, _really_ have to. by proceeding, you acknowledge the risk of breaking your own code or apps that use your code.
# <img src="https://github.com/aidenybai/bippy/blob/main/.github/public/bippy.png?raw=true" width="60" align="center" /> bippy
[![version](https://img.shields.io/npm/v/bippy?style=flat&colorA=000000&colorB=000000)](https://npmjs.com/package/bippy)
[![downloads](https://img.shields.io/npm/dt/bippy.svg?style=flat&colorA=000000&colorB=000000)](https://npmjs.com/package/bippy)
bippy is a toolkit to **hack into react internals**
by default, you cannot access react internals. bippy bypasses this by “pretending” to be react devtools, giving you access to the fiber tree and other internals.
- works outside of react: no react code modification needed
- utility functions that work across modern react (v17-19)
- no prior react source code knowledge required
```jsx
import { instrument, traverseFiber } from "bippy"; // must be imported BEFORE react
instrument({
onCommitFiberRoot(rendererID, root) {
traverseFiber(root.current, (fiber) => {
// prints every fiber in the current React tree
console.log("fiber:", fiber);
});
},
});
```
## how it works & motivation
bippy allows you to **access** and **use** react fibers **outside** of react components.
a react fiber is a “unit of execution.” this means react will do something based on the data in a fiber. each fiber either represents a composite (function/class component) or a host (dom element).
> here is a [live visualization](https://jser.pro/ddir/rie?reactVersion=18.3.1&snippetKey=hq8jm2ylzb9u8eh468) of what the fiber tree looks like, and here is a [deep dive article](https://jser.dev/2023-07-18-how-react-rerenders/).
fibers are useful because they contain information about the react app (component props, state, contexts, etc.). a simplified version of a fiber looks roughly like this:
```typescript
interface Fiber {
// component type (function/class)
type: any;
child: Fiber | null;
sibling: Fiber | null;
// stateNode is the host fiber (e.g. DOM element)
stateNode: Node | null;
// parent fiber
return: Fiber | null;
// the previous or current version of the fiber
alternate: Fiber | null;
// saved props input
memoizedProps: any;
// state (useState, useReducer, useSES, etc.)
memoizedState: any;
// contexts (useContext)
dependencies: Dependencies | null;
// effects (useEffect, useLayoutEffect, etc.)
updateQueue: any;
}
```
here, the `child`, `sibling`, and `return` properties are pointers to other fibers in the tree.
additionally, `memoizedProps`, `memoizedState`, and `dependencies` are the fiber's props, state, and contexts.
while all of the information is there, it's awkward to work with, and changes frequently across different versions of react. bippy simplifies this by providing utility functions like:
- `traverseRenderedFibers` to detect renders and `traverseFiber` to traverse the overall fiber tree
- _(instead of `child`, `sibling`, and `return` pointers)_
- `traverseProps`, `traverseState`, and `traverseContexts` to traverse the fiber's props, state, and contexts
- _(instead of `memoizedProps`, `memoizedState`, and `dependencies`)_
however, react doesn't expose fibers to you directly. so, we have to hack our way around to access them.
luckily, react [reads from a property](https://github.com/facebook/react/blob/6a4b46cd70d2672bc4be59dcb5b8dede22ed0cef/packages/react-reconciler/src/ReactFiberDevToolsHook.js#L48) in the window object: `window.__REACT_DEVTOOLS_GLOBAL_HOOK__` and runs handlers on it when certain events happen. this property must exist before react's bundle is executed. this is intended for react devtools, but we can use it to our advantage.
here's what it roughly looks like:
```typescript
interface __REACT_DEVTOOLS_GLOBAL_HOOK__ {
// list of renderers (react-dom, react-native, etc.)
renderers: Map<RendererID, reactRenderer>;
// called when react has rendered everything for an update and the fiber tree is fully built and ready to
// apply changes to the host tree (e.g. DOM mutations)
onCommitFiberRoot: (rendererID: RendererID, root: FiberRoot, commitPriority?: number) => void;
// called when effects run
onPostCommitFiberRoot: (rendererID: RendererID, root: FiberRoot) => void;
// called when a specific fiber unmounts
onCommitFiberUnmount: (rendererID: RendererID, fiber: Fiber) => void;
}
```
bippy works by monkey-patching `window.__REACT_DEVTOOLS_GLOBAL_HOOK__` with our own custom handlers. bippy simplifies this by providing utility functions like:
- `instrument` to safely patch `window.__REACT_DEVTOOLS_GLOBAL_HOOK__`
- _(instead of directly mutating `onCommitFiberRoot`, …)_
- `traverseRenderedFibers` to traverse the fiber tree and determine which fibers have actually rendered
- _(instead of `child`, `sibling`, and `return` pointers)_
- `traverseFiber` to traverse the fiber tree, regardless of whether it has rendered
- _(instead of `child`, `sibling`, and `return` pointers)_
- `setFiberId` / `getFiberId` to set and get a fiber's id
- _(instead of anonymous fibers with no identity)_
## how to use
we recommend installing via npm.
import this package before your react app runs. it adds a special object to the global scope that react reports its internals to (react devtools uses the same mechanism). as soon as react loads and attaches, bippy starts collecting data about what is going on in react's internals.
```shell
npm install bippy
```
since bippy must load before react, some bundlers need specific configuration to get the import order right.
### next.js
in next.js 15.3+, use the [`instrumentation-client.js`](https://nextjs.org/docs/app/api-reference/file-conventions/instrumentation-client) file to ensure bippy loads before react. create this file at the root of your application (or inside the `src` folder if you're using the src directory structure):
```typescript
// instrumentation-client.ts
import "bippy";
```
this file executes before react hydration, making it the ideal place to initialize bippy.
### vite
in vite, import bippy at the very top of your main entry point (typically `src/main.tsx` or `src/main.ts`) before any react imports:
```typescript
// src/main.tsx
import "bippy";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
// ... rest of your code
```
the import order is critical: import bippy before any react packages.
> **note for library maintainers**: if you're building a library and want to define your own utility functions while minimizing bundle size, you can use `bippy/install-hook-only` (~90 bytes) instead of the main `bippy` export. this only installs the react devtools hook without importing any utility functions, allowing you to import only what you need from `bippy/core` or define your own fiber utilities. that said, the full `bippy` package is only ~4 KB gzipped, so bundle size is rarely a concern.
> ```typescript
> import "bippy/install-hook-only"; // only installs the hook
> import { getRDTHook, traverseFiber } from "bippy/core"; // import only what you need
> import * as React from "react"; // import react AFTER the hook is installed
>
> const hook = getRDTHook();
> // define your own utilities or use only specific ones
> ```
## API reference
### instrument
patches `window.__REACT_DEVTOOLS_GLOBAL_HOOK__` with your handlers. import bippy before react, and call `instrument` before any other methods.
bippy patches each hook event once and dispatches it to a set of listeners, so multiple `instrument` calls compose instead of replacing each other. `instrument` returns an unsubscribe function that removes exactly the handlers you registered (also a `Disposable`, so it works with `using`).
```typescript
import { instrument } from "bippy"; // must be imported BEFORE react
import * as React from "react";
const unsubscribe = instrument({
onCommitFiberRoot(rendererID, root) {
console.log("root ready to commit", root);
},
onPostCommitFiberRoot(rendererID, root) {
console.log("root with effects committed", root);
},
onCommitFiberUnmount(rendererID, fiber) {
console.log("fiber unmounted", fiber);
},
});
// later, stop listening (other instrument() subscribers keep working)
unsubscribe();
```
### getRDTHook
returns the `window.__REACT_DEVTOOLS_GLOBAL_HOOK__` object. great for advanced use cases, such as accessing or modifying the `renderers` property.
```typescript
import { getRDTHook } from "bippy";
const hook = getRDTHook();
console.log(hook);
```
### traverseRenderedFibers
not every fiber in the fiber tree renders. `traverseRenderedFibers` allows you to traverse the fiber tree and determine which fibers have actually rendered.
```typescript
import { instrument, traverseRenderedFibers } from "bippy"; // must be imported BEFORE react
import * as React from "react";
instrument({
onCommitFiberRoot(rendererID, root) {
traverseRenderedFibers(root, (fiber) => {
console.log("fiber rendered", fiber);
});
},
});
```
### traverseFiber
calls a callback on every fiber in the fiber tree.
```typescript
import { instrument, traverseFiber } from "bippy"; // must be imported BEFORE react
import * as React from "react";
instrument({
onCommitFiberRoot(rendererID, root) {
traverseFiber(root.current, (fiber) => {
console.log(fiber);
});
},
});
```
### traverseProps
traverses the props of a fiber.
```typescript
import { traverseProps } from "bippy";
// ...
traverseProps(fiber, (propName, next, prev) => {
console.log(propName, next, prev);
});
```
### traverseState
traverses the state (`useState`, `useReducer`, etc.) and effects that set state of a fiber.
```typescript
import { traverseState } from "bippy";
// ...
traverseState(fiber, (next, prev) => {
console.log(next, prev);
});
```
### traverseContexts
traverses the contexts (`useContext`) of a fiber.
```typescript
import { traverseContexts } from "bippy";
// ...
traverseContexts(fiber, (next, prev) => {
console.log(next, prev);
});
```
### setFiberId / getFiberId
set and get a persistent identity for a fiber. by default, fibers are anonymous and have no identity.
```typescript
import { setFiberId, getFiberId } from "bippy";
// ...
setFiberId(fiber);
console.log("unique id for fiber:", getFiberId(fiber));
```
### isHostFiber
returns `true` if the fiber is a host fiber (e.g., a DOM node in react-dom).
```typescript
import { isHostFiber } from "bippy";
if (isHostFiber(fiber)) {
console.log("fiber is a host fiber");
}
```
### isCompositeFiber
returns `true` if the fiber is a composite fiber. composite fibers represent class components, function components, memoized components, and so on (anything that can actually render output).
```typescript
import { isCompositeFiber } from "bippy";
if (isCompositeFiber(fiber)) {
console.log("fiber is a composite fiber");
}
```
### getDisplayName
returns the display name of the fiber's component, falling back to the component's function or class name if available.
```typescript
import { getDisplayName } from "bippy";
console.log(getDisplayName(fiber));
```
### getType
returns the underlying type (the component definition) for a given fiber. for example, this could be a function component or class component.
```jsx
import { getType } from "bippy";
import { memo } from "react";
const RealComponent = () => {
return <div>hello</div>;
};
const MemoizedComponent = memo(() => {
return <div>hello</div>;
});
console.log(getType(fiberForMemoizedComponent) === RealComponent);
```
### getNearestHostFiber / getNearestHostFibers
`getNearestHostFiber` returns the closest host fiber above or below a given fiber. `getNearestHostFibers` returns all host fibers associated with the provided fiber and its subtree.
```jsx
import { getNearestHostFiber, getNearestHostFibers } from "bippy";
// ...
function Component() {
return (
<>
<div>hello</div>
<div>world</div>
</>
);
}
console.log(getNearestHostFiber(fiberForComponent)); // <div>hello</div>
console.log(getNearestHostFibers(fiberForComponent)); // [<div>hello</div>, <div>world</div>]
```
### getTimings
returns the self and total render times for the fiber.
```typescript
// timings don't exist in react production builds
if (fiber.actualDuration !== undefined) {
const { selfTime, totalTime } = getTimings(fiber);
console.log(selfTime, totalTime);
}
```
### getFiberStack
returns an array representing the stack of fibers from the current fiber up to the root.
```typescript
[fiber, fiber.return, fiber.return.return, ...]
```
### getMutatedHostFibers
returns an array of all host fibers that have committed and rendered in the provided fiber's subtree.
```typescript
import { getMutatedHostFibers } from "bippy";
console.log(getMutatedHostFibers(fiber));
```
### isValidFiber
returns `true` if the given object is a valid React Fiber (i.e., has a tag, stateNode, return, child, sibling, etc.).
```typescript
import { isValidFiber } from "bippy";
console.log(isValidFiber(fiber));
```
### getFiberFromHostInstance
returns the fiber associated with a given host instance (e.g., a DOM element).
```typescript
import { getFiberFromHostInstance } from "bippy";
const fiber = getFiberFromHostInstance(document.querySelector("div"));
console.log(fiber);
```
### getLatestFiber
returns the latest fiber (since it may be double-buffered). usually use this in combination with `getFiberFromHostInstance`.
```typescript
import { getLatestFiber } from "bippy";
const latestFiber = getLatestFiber(getFiberFromHostInstance(document.querySelector("div")));
console.log(latestFiber);
```
### overrideProps
overrides component props at runtime by modifying the fiber's props.
```typescript
import { overrideProps } from "bippy";
// override props on a fiber
overrideProps(fiber, {
title: "new title",
config: {
enabled: true,
count: 42,
},
});
```
the function accepts a fiber and a partial object containing the props to override. bippy automatically flattens nested objects into property paths.
### overrideHookState
overrides hook state (`useState`, `useReducer`, etc.) at runtime by hook id.
```typescript
import { overrideHookState } from "bippy";
// override the first hook (id: 0) with a new value
overrideHookState(fiber, 0, "new state value");
// override nested state object
overrideHookState(fiber, 1, {
user: {
name: "john",
age: 30,
},
});
```
the hook id parameter corresponds to the order of hooks in the component (0-indexed). pass either a primitive value or an object for nested state updates.
### overrideContext
overrides react context values at runtime by finding the appropriate context provider.
```typescript
import { overrideContext } from "bippy";
// override context value
overrideContext(fiber, MyContext, {
theme: "dark",
user: {
id: 123,
name: "jane",
},
});
// override with primitive value
overrideContext(fiber, ThemeContext, "dark");
```
the function traverses up the fiber tree to find the context provider matching the provided context type and overrides its value.
### getSource
gets the source code location of a composite fiber.
```typescript
import { getSource } from "bippy/source";
// random fiber on the DOM
const hostFiber = getFiberFromHostInstance(document.querySelector("div"));
// get nearest composite fiber up the tree
const compositeFiber = traverseFiber(
hostFiber,
(fiber) => {
if (isCompositeFiber(fiber)) {
return fiber;
}
},
true,
);
const source = await getSource(compositeFiber);
// {
// columnNumber: 12,
// fileName: 'path/to/file.tsx',
// lineNumber: 12,
// }
```
> **caveats:**
>
> - only available in dev mode
> - only works for composite fibers (function/class components)
> - captures the location where the component is _used_, not where it's _defined_
> - in react 18, resolves `_debugSource` directly (see [react#31981](https://github.com/facebook/react/issues/31981))
> - in react >18, `_debugSource` is not available for host fibers
### getOwnerStack / getParentStack
returns a symbolicated stack of components above a fiber.
`getOwnerStack` walks the chain of components that _created_ this fiber's JSX (react's `_debugOwner` chain), with exact creation-site locations on react 19, including server component owners. wrappers that merely render `{children}` don't appear. it automatically falls back to `getParentStack` when no usable owner frames exist (e.g. react <19).
`getParentStack` walks _all_ ancestors in the render tree (the fiber's `return` chain), including `{children}` wrappers. works on every react version.
```typescript
import { getOwnerStack, getParentStack } from "bippy/source";
const ownerFrames = await getOwnerStack(fiber);
// [{ functionName: "Button", fileName: "src/button.tsx", lineNumber: 12, ... }, ...]
const parentFrames = await getParentStack(fiber);
// includes every wrapper between the fiber and the root
```
### instrumentReactRefresh
subscribes to fast refresh (HMR) updates from `bippy/react-refresh`. works with any bundler that uses react-refresh (vite, next.js webpack, next.js turbopack, metro) without bundler-specific code: bippy auto-detects the bundler's HMR transport and augments each update with the hot-updated source file paths.
the handler runs after react has re-rendered with the new component types, so `updatedFibers`/`staleFibers` are the mounted fibers matching the hot-swapped component types.
returns an unsubscribe function (a no-op during SSR, so no environment checks needed). the returned function is also a `Disposable`, so it works with `using`.
```typescript
import { instrumentReactRefresh } from "bippy/react-refresh";
import { getDisplayName } from "bippy";
const unsubscribe = instrumentReactRefresh({
onRefresh(update) {
for (const fiber of update.updatedFibers) {
console.log("hot updated:", getDisplayName(fiber.type));
}
console.log("changed files:", update.filePaths);
},
});
// later
unsubscribe();
```
## example
here's a mini toy version of [`react-scan`](https://github.com/aidenybai/react-scan) that highlights renders in your app.
```javascript
import { instrument, getNearestHostFiber, traverseRenderedFibers } from "bippy"; // must be imported BEFORE react
const highlightFiber = (fiber) => {
if (!(fiber.stateNode instanceof HTMLElement)) return;
// fiber.stateNode is a DOM element
const rect = fiber.stateNode.getBoundingClientRect();
const highlight = document.createElement("div");
highlight.style.border = "1px solid red";
highlight.style.position = "fixed";
highlight.style.top = `${rect.top}px`;
highlight.style.left = `${rect.left}px`;
highlight.style.width = `${rect.width}px`;
highlight.style.height = `${rect.height}px`;
highlight.style.zIndex = "999999999";
document.documentElement.appendChild(highlight);
setTimeout(() => {
document.documentElement.removeChild(highlight);
}, 100);
};
/**
* `instrument` is a function that installs the react DevTools global
* hook and allows you to set up custom handlers for react fiber events.
*/
instrument({
/**
* `onCommitFiberRoot` is a handler that is called when react is
* ready to commit a fiber root. this means that react is has
* rendered your entire app and is ready to apply changes to
* the host tree (e.g. via DOM mutations).
*/
onCommitFiberRoot(rendererID, root) {
/**
* `traverseRenderedFibers` traverses the fiber tree and determines which
* fibers have actually rendered.
*
* A fiber tree contains many fibers that may have not rendered. this
* can be because it bailed out (e.g. `useMemo`) or because it wasn't
* actually rendered (if <Child> re-rendered, then <Parent> didn't
* actually render, but exists in the fiber tree).
*/
traverseRenderedFibers(root, (fiber) => {
/**
* `getNearestHostFiber` is a utility function that finds the
* nearest host fiber to a given fiber.
*
* a host fiber for `react-dom` is a fiber that has a DOM element
* as its `stateNode`.
*/
const hostFiber = getNearestHostFiber(fiber);
highlightFiber(hostFiber);
});
},
});
```
## glossary
- fiber: a “unit of execution” in react, representing a component or dom element
- commit: the process of applying changes to the host tree (e.g. DOM mutations)
- render: the process of building the fiber tree by executing component function/classes
- host tree: the tree of UI elements that react mutates (e.g. DOM elements)
- reconciler (or “renderer”): custom bindings for react, e.g. react-dom, react-native, react-three-fiber, etc to mutate the host tree
- `rendererID`: the id of the reconciler, starting at 1 (can be from multiple reconciler instances)
- `root`: a special `FiberRoot` type that contains the container fiber (the one you pass to `ReactDOM.createRoot`) in the `current` property
- `onCommitFiberRoot`: called when react is ready to commit a fiber root
- `onPostCommitFiberRoot`: called when react has committed a fiber root and effects have run
- `onCommitFiberUnmount`: called when a fiber unmounts
## misc
we initially created bippy for [react-scan](https://github.com/aidenybai/react-scan), which ships with safeguards so it only runs in development or error-guarded in production.
if you're seeking more robust solutions, you might consider [its-fine](https://github.com/pmndrs/its-fine) for accessing fibers within react using hooks, or [react-devtools-inline](https://www.npmjs.com/package/react-devtools-inline) for a headful interface.
if you plan to use this project beyond experimentation, please review [react-scan's source code](https://github.com/aidenybai/react-scan) to understand our safeguarding practices.
the original bippy character is owned and created by [@dairyfreerice](https://www.instagram.com/dairyfreerice). this project is not related to the bippy brand, i just think the character is cute.

9
node_modules/bippy/dist/core.cjs generated vendored Normal file

File diff suppressed because one or more lines are too long

214
node_modules/bippy/dist/core.d.cts generated vendored Normal file
View File

@@ -0,0 +1,214 @@
import { A as ReactRenderer, E as ReactDevToolsGlobalHook, a as ContextDependency, d as FiberRoot, t as Unsubscribe, u as Fiber, v as MemoizedState } from "./unsubscribe.cjs";
import * as React from "react";
//#region src/rdt-hook.d.ts
declare const version: string | undefined;
declare const BIPPY_INSTRUMENTATION_STRING: string;
declare const isRealReactDevtools: (rdtHook?: ReactDevToolsGlobalHook | undefined | null) => boolean;
declare const isReactRefresh: (rdtHook?: ReactDevToolsGlobalHook | undefined | null) => boolean;
declare const _onActiveListeners: Set<() => unknown>;
declare const _renderers: Set<ReactRenderer>;
/**
* Subscribes to future renderer injections into the DevTools hook. The
* single shared inject wrapper lets multiple consumers (override methods,
* react-refresh, user code) observe renderers without stacking patches
* whose restore order matters. Returns an unsubscribe function.
*/
declare const onRendererInject: (listener: (renderer: ReactRenderer) => void) => Unsubscribe;
declare const installRDTHook: (onActive?: () => unknown) => ReactDevToolsGlobalHook;
declare const patchRDTHook: (onActive?: () => unknown) => void;
declare const hasRDTHook: () => boolean;
/**
* Returns the current React DevTools global hook.
*/
declare const getRDTHook: (onActive?: () => unknown) => ReactDevToolsGlobalHook;
declare const isClientEnvironment: () => boolean;
/**
* Usually used purely for side effect
*/
declare const safelyInstallRDTHook: () => void;
//#endregion
//#region src/core.d.ts
declare const FunctionComponentTag = 0;
declare const ClassComponentTag = 1;
declare const HostRootTag = 3;
declare const HostPortalTag = 4;
declare const HostComponentTag = 5;
declare const HostTextTag = 6;
declare const FragmentTag = 7;
declare const ContextConsumerTag = 9;
declare const ForwardRefTag = 11;
declare const SuspenseComponentTag = 13;
declare const MemoComponentTag = 14;
declare const SimpleMemoComponentTag = 15;
declare const LazyComponentTag = 16;
declare const DehydratedSuspenseComponentTag = 18;
declare const SuspenseListComponentTag = 19;
declare const OffscreenComponentTag = 22;
declare const LegacyHiddenComponentTag = 23;
declare const HostHoistableTag = 26;
declare const HostSingletonTag = 27;
declare const ActivityComponentTag = 28;
declare const ViewTransitionComponentTag = 30;
declare const CONCURRENT_MODE_NUMBER = 60111;
declare const ELEMENT_TYPE_SYMBOL_STRING = "Symbol(react.element)";
declare const TRANSITIONAL_ELEMENT_TYPE_SYMBOL_STRING = "Symbol(react.transitional.element)";
declare const CONCURRENT_MODE_SYMBOL_STRING = "Symbol(react.concurrent_mode)";
declare const DEPRECATED_ASYNC_MODE_SYMBOL_STRING = "Symbol(react.async_mode)";
declare const CONCURRENT_MODE_SYMBOL_DESCRIPTION = "react.concurrent_mode";
declare const DEPRECATED_ASYNC_MODE_SYMBOL_DESCRIPTION = "react.async_mode";
/**
* Returns `true` if object is a React Element.
*
* @see https://react.dev/reference/react/isValidElement
*/
declare const isValidElement: (element: unknown) => element is React.ReactElement;
/**
* Returns `true` if object is a React Fiber.
*/
declare const isValidFiber: (fiber: unknown) => fiber is Fiber;
/**
* Returns `true` if fiber is a host fiber. Host fibers are DOM nodes in react-dom, `View` in react-native, etc.
*
* @see https://reactnative.dev/architecture/glossary#host-view-tree-and-host-view
*/
declare const isHostFiber: (fiber: Fiber) => boolean;
/**
* Returns `true` if fiber is a composite fiber. Composite fibers are fibers that can render (like functional components, class components, etc.)
*
* @see https://reactnative.dev/architecture/glossary#react-composite-components
*/
declare const isCompositeFiber: (fiber: Fiber) => boolean;
/**
* Returns `true` if the object is a {@link Fiber}
*/
declare const isFiber: (maybeFiber: unknown) => maybeFiber is Fiber;
/**
* Traverses up or down a {@link Fiber}'s contexts, return `true` to stop and select the current and previous context value.
*/
declare const traverseContexts: (fiber: Fiber, selector: (nextValue: ContextDependency<unknown> | null | undefined, prevValue: ContextDependency<unknown> | null | undefined) => boolean | void) => boolean;
/**
* Traverses up or down a {@link Fiber}'s states, return `true` to stop and select the current and previous state value. This stores both state values and effects.
*/
declare const traverseState: (fiber: Fiber, selector: (nextValue: MemoizedState | null | undefined, prevValue: MemoizedState | null | undefined) => boolean | void) => boolean;
/**
* Traverses up or down a {@link Fiber}'s props, return `true` to stop and select the current and previous props value.
*/
declare const traverseProps: (fiber: Fiber, selector: (propName: string, nextValue: unknown, prevValue: unknown) => boolean | void) => boolean;
/**
* Returns `true` if the {@link Fiber} has rendered. Note that this does not mean the fiber has rendered in the current commit, just that it has rendered in the past.
*/
declare const didFiberRender: (fiber: Fiber) => boolean;
/**
* Returns `true` if the {@link Fiber} has committed. Note that this does not mean the fiber has committed in the current commit, just that it has committed in the past.
*/
declare const didFiberCommit: (fiber: Fiber) => boolean;
/**
* Returns all host {@link Fiber}s that have committed and rendered.
*/
declare const getMutatedHostFibers: (fiber: Fiber) => Fiber[];
/**
* Returns the stack of {@link Fiber}s from the current fiber to the root fiber.
*
* @example
* ```ts
* [fiber, fiber.return, fiber.return.return, ...]
* ```
*/
declare const getFiberStack: (fiber: Fiber) => Fiber[];
/**
* Returns the nearest host {@link Fiber} to the current {@link Fiber}.
*/
declare const getNearestHostFiber: (fiber: Fiber, ascending?: boolean) => Fiber | null;
/**
* Returns all host {@link Fiber}s in the tree that are associated with the current {@link Fiber}.
*/
declare const getNearestHostFibers: (fiber: Fiber) => Fiber[];
/**
* Traverses up or down a {@link Fiber}, return `true` to stop and select a node.
*/
declare function traverseFiber(fiber: Fiber | null, selector: (node: Fiber) => boolean | void, ascending?: boolean): Fiber | null;
declare function traverseFiber(fiber: Fiber | null, selector: (node: Fiber) => Promise<boolean | void>, ascending?: boolean): Promise<Fiber | null>;
/**
* Returns the timings of the {@link Fiber}.
*
* @example
* ```ts
* const { selfTime, totalTime } = getTimings(fiber);
* console.log(selfTime, totalTime);
* ```
*/
declare const getTimings: (fiber?: Fiber | null) => {
selfTime: number;
totalTime: number;
};
/**
* Returns `true` if the {@link Fiber} uses React Compiler's memo cache.
*/
declare const hasMemoCache: (fiber: Fiber) => boolean;
/**
* Returns the type (e.g. component definition) of the {@link Fiber}
*/
declare const getType: (type: unknown) => null | React.ComponentType<unknown>;
/**
* Returns the display name of the {@link Fiber} type.
*/
declare const getDisplayName: (type: unknown) => null | string;
/**
* Returns the build type of the React renderer.
*/
declare const detectReactBuildType: (renderer: ReactRenderer) => "development" | "production";
/**
* Returns `true` if bippy's instrumentation is active.
*/
declare const isInstrumentationActive: () => boolean;
declare const _fiberRoots: Set<any>;
/**
* Returns the latest fiber (since it may be double-buffered).
*/
declare const getLatestFiber: (fiber: Fiber) => Fiber;
type RenderHandler = <S>(fiber: Fiber, phase: RenderPhase, state?: S) => unknown;
type RenderPhase = "mount" | "unmount" | "update";
declare const setFiberId: (fiber: Fiber, id?: number) => void;
declare const getFiberId: (fiber: Fiber) => number;
/**
* Creates a fiber visitor function. Must pass a fiber root and a render handler.
* @example
* traverseRenderedFibers(root, (fiber, phase) => {
* console.log(phase)
* })
*/
declare const traverseRenderedFibers: (root: FiberRoot, onRender: RenderHandler) => void;
declare const overrideProps: (fiber: Fiber, partialValue: Record<string, unknown>) => void;
declare const overrideHookState: (fiber: Fiber, id: number, partialValue: unknown) => void;
declare const overrideContext: (fiber: Fiber, contextType: unknown, partialValue: unknown) => void;
interface InstrumentationOptions {
name?: string;
onActive?: () => unknown;
onCommitFiberRoot?: (rendererID: number, root: FiberRoot, priority: number | void) => unknown;
onCommitFiberUnmount?: (rendererID: number, fiber: Fiber) => unknown;
onPostCommitFiberRoot?: (rendererID: number, root: FiberRoot) => unknown;
onScheduleFiberRoot?: (rendererID: number, root: FiberRoot, children: React.ReactNode) => unknown;
}
/**
* Instruments the DevTools hook. Each hook event is patched once and
* dispatches to a set of listeners, so multiple `instrument` calls compose
* without stacking patches. Returns an unsubscribe function that removes
* exactly the handlers this call registered.
* The returned function is also a `Disposable`, so it composes with other
* bippy subscriptions through `using`.
* @example
* const unsubscribe = instrument({
* onActive() {
* console.log('initialized');
* },
* onCommitFiberRoot(rendererID, root) {
* console.log('fiberRoot', root.current)
* },
* });
* unsubscribe();
*/
declare const instrument: (options: InstrumentationOptions) => Unsubscribe;
declare const getFiberFromHostInstance: <T>(hostInstance: T) => Fiber | null;
//#endregion
export { isValidFiber as $, TRANSITIONAL_ELEMENT_TYPE_SYMBOL_STRING as A, getLatestFiber as B, MemoComponentTag as C, SimpleMemoComponentTag as D, RenderPhase as E, didFiberRender as F, getType as G, getNearestHostFiber as H, getDisplayName as I, isCompositeFiber as J, hasMemoCache as K, getFiberFromHostInstance as L, _fiberRoots as M, detectReactBuildType as N, SuspenseComponentTag as O, didFiberCommit as P, isValidElement as Q, getFiberId as R, LegacyHiddenComponentTag as S, RenderHandler as T, getNearestHostFibers as U, getMutatedHostFibers as V, getTimings as W, isHostFiber as X, isFiber as Y, isInstrumentationActive as Z, HostRootTag as _, isRealReactDevtools as _t, ClassComponentTag as a, traverseFiber as at, InstrumentationOptions as b, safelyInstallRDTHook as bt, DEPRECATED_ASYNC_MODE_SYMBOL_STRING as c, traverseState as ct, ForwardRefTag as d, _renderers as dt, overrideContext as et, FragmentTag as f, getRDTHook as ft, HostPortalTag as g, isReactRefresh as gt, HostHoistableTag as h, isClientEnvironment as ht, CONCURRENT_MODE_SYMBOL_STRING as i, traverseContexts as it, ViewTransitionComponentTag as j, SuspenseListComponentTag as k, DehydratedSuspenseComponentTag as l, BIPPY_INSTRUMENTATION_STRING as lt, HostComponentTag as m, installRDTHook as mt, CONCURRENT_MODE_NUMBER as n, overrideProps as nt, ContextConsumerTag as o, traverseProps as ot, FunctionComponentTag as p, hasRDTHook as pt, instrument as q, CONCURRENT_MODE_SYMBOL_DESCRIPTION as r, setFiberId as rt, DEPRECATED_ASYNC_MODE_SYMBOL_DESCRIPTION as s, traverseRenderedFibers as st, ActivityComponentTag as t, overrideHookState as tt, ELEMENT_TYPE_SYMBOL_STRING as u, _onActiveListeners as ut, HostSingletonTag as v, onRendererInject as vt, OffscreenComponentTag as w, LazyComponentTag as x, version as xt, HostTextTag as y, patchRDTHook as yt, getFiberStack as z };

214
node_modules/bippy/dist/core.d.ts generated vendored Normal file
View File

@@ -0,0 +1,214 @@
import { A as ReactRenderer, E as ReactDevToolsGlobalHook, a as ContextDependency, d as FiberRoot, t as Unsubscribe, u as Fiber, v as MemoizedState } from "./unsubscribe.js";
import * as React from "react";
//#region src/rdt-hook.d.ts
declare const version: string | undefined;
declare const BIPPY_INSTRUMENTATION_STRING: string;
declare const isRealReactDevtools: (rdtHook?: ReactDevToolsGlobalHook | undefined | null) => boolean;
declare const isReactRefresh: (rdtHook?: ReactDevToolsGlobalHook | undefined | null) => boolean;
declare const _onActiveListeners: Set<() => unknown>;
declare const _renderers: Set<ReactRenderer>;
/**
* Subscribes to future renderer injections into the DevTools hook. The
* single shared inject wrapper lets multiple consumers (override methods,
* react-refresh, user code) observe renderers without stacking patches
* whose restore order matters. Returns an unsubscribe function.
*/
declare const onRendererInject: (listener: (renderer: ReactRenderer) => void) => Unsubscribe;
declare const installRDTHook: (onActive?: () => unknown) => ReactDevToolsGlobalHook;
declare const patchRDTHook: (onActive?: () => unknown) => void;
declare const hasRDTHook: () => boolean;
/**
* Returns the current React DevTools global hook.
*/
declare const getRDTHook: (onActive?: () => unknown) => ReactDevToolsGlobalHook;
declare const isClientEnvironment: () => boolean;
/**
* Usually used purely for side effect
*/
declare const safelyInstallRDTHook: () => void;
//#endregion
//#region src/core.d.ts
declare const FunctionComponentTag = 0;
declare const ClassComponentTag = 1;
declare const HostRootTag = 3;
declare const HostPortalTag = 4;
declare const HostComponentTag = 5;
declare const HostTextTag = 6;
declare const FragmentTag = 7;
declare const ContextConsumerTag = 9;
declare const ForwardRefTag = 11;
declare const SuspenseComponentTag = 13;
declare const MemoComponentTag = 14;
declare const SimpleMemoComponentTag = 15;
declare const LazyComponentTag = 16;
declare const DehydratedSuspenseComponentTag = 18;
declare const SuspenseListComponentTag = 19;
declare const OffscreenComponentTag = 22;
declare const LegacyHiddenComponentTag = 23;
declare const HostHoistableTag = 26;
declare const HostSingletonTag = 27;
declare const ActivityComponentTag = 28;
declare const ViewTransitionComponentTag = 30;
declare const CONCURRENT_MODE_NUMBER = 60111;
declare const ELEMENT_TYPE_SYMBOL_STRING = "Symbol(react.element)";
declare const TRANSITIONAL_ELEMENT_TYPE_SYMBOL_STRING = "Symbol(react.transitional.element)";
declare const CONCURRENT_MODE_SYMBOL_STRING = "Symbol(react.concurrent_mode)";
declare const DEPRECATED_ASYNC_MODE_SYMBOL_STRING = "Symbol(react.async_mode)";
declare const CONCURRENT_MODE_SYMBOL_DESCRIPTION = "react.concurrent_mode";
declare const DEPRECATED_ASYNC_MODE_SYMBOL_DESCRIPTION = "react.async_mode";
/**
* Returns `true` if object is a React Element.
*
* @see https://react.dev/reference/react/isValidElement
*/
declare const isValidElement: (element: unknown) => element is React.ReactElement;
/**
* Returns `true` if object is a React Fiber.
*/
declare const isValidFiber: (fiber: unknown) => fiber is Fiber;
/**
* Returns `true` if fiber is a host fiber. Host fibers are DOM nodes in react-dom, `View` in react-native, etc.
*
* @see https://reactnative.dev/architecture/glossary#host-view-tree-and-host-view
*/
declare const isHostFiber: (fiber: Fiber) => boolean;
/**
* Returns `true` if fiber is a composite fiber. Composite fibers are fibers that can render (like functional components, class components, etc.)
*
* @see https://reactnative.dev/architecture/glossary#react-composite-components
*/
declare const isCompositeFiber: (fiber: Fiber) => boolean;
/**
* Returns `true` if the object is a {@link Fiber}
*/
declare const isFiber: (maybeFiber: unknown) => maybeFiber is Fiber;
/**
* Traverses up or down a {@link Fiber}'s contexts, return `true` to stop and select the current and previous context value.
*/
declare const traverseContexts: (fiber: Fiber, selector: (nextValue: ContextDependency<unknown> | null | undefined, prevValue: ContextDependency<unknown> | null | undefined) => boolean | void) => boolean;
/**
* Traverses up or down a {@link Fiber}'s states, return `true` to stop and select the current and previous state value. This stores both state values and effects.
*/
declare const traverseState: (fiber: Fiber, selector: (nextValue: MemoizedState | null | undefined, prevValue: MemoizedState | null | undefined) => boolean | void) => boolean;
/**
* Traverses up or down a {@link Fiber}'s props, return `true` to stop and select the current and previous props value.
*/
declare const traverseProps: (fiber: Fiber, selector: (propName: string, nextValue: unknown, prevValue: unknown) => boolean | void) => boolean;
/**
* Returns `true` if the {@link Fiber} has rendered. Note that this does not mean the fiber has rendered in the current commit, just that it has rendered in the past.
*/
declare const didFiberRender: (fiber: Fiber) => boolean;
/**
* Returns `true` if the {@link Fiber} has committed. Note that this does not mean the fiber has committed in the current commit, just that it has committed in the past.
*/
declare const didFiberCommit: (fiber: Fiber) => boolean;
/**
* Returns all host {@link Fiber}s that have committed and rendered.
*/
declare const getMutatedHostFibers: (fiber: Fiber) => Fiber[];
/**
* Returns the stack of {@link Fiber}s from the current fiber to the root fiber.
*
* @example
* ```ts
* [fiber, fiber.return, fiber.return.return, ...]
* ```
*/
declare const getFiberStack: (fiber: Fiber) => Fiber[];
/**
* Returns the nearest host {@link Fiber} to the current {@link Fiber}.
*/
declare const getNearestHostFiber: (fiber: Fiber, ascending?: boolean) => Fiber | null;
/**
* Returns all host {@link Fiber}s in the tree that are associated with the current {@link Fiber}.
*/
declare const getNearestHostFibers: (fiber: Fiber) => Fiber[];
/**
* Traverses up or down a {@link Fiber}, return `true` to stop and select a node.
*/
declare function traverseFiber(fiber: Fiber | null, selector: (node: Fiber) => boolean | void, ascending?: boolean): Fiber | null;
declare function traverseFiber(fiber: Fiber | null, selector: (node: Fiber) => Promise<boolean | void>, ascending?: boolean): Promise<Fiber | null>;
/**
* Returns the timings of the {@link Fiber}.
*
* @example
* ```ts
* const { selfTime, totalTime } = getTimings(fiber);
* console.log(selfTime, totalTime);
* ```
*/
declare const getTimings: (fiber?: Fiber | null) => {
selfTime: number;
totalTime: number;
};
/**
* Returns `true` if the {@link Fiber} uses React Compiler's memo cache.
*/
declare const hasMemoCache: (fiber: Fiber) => boolean;
/**
* Returns the type (e.g. component definition) of the {@link Fiber}
*/
declare const getType: (type: unknown) => null | React.ComponentType<unknown>;
/**
* Returns the display name of the {@link Fiber} type.
*/
declare const getDisplayName: (type: unknown) => null | string;
/**
* Returns the build type of the React renderer.
*/
declare const detectReactBuildType: (renderer: ReactRenderer) => "development" | "production";
/**
* Returns `true` if bippy's instrumentation is active.
*/
declare const isInstrumentationActive: () => boolean;
declare const _fiberRoots: Set<any>;
/**
* Returns the latest fiber (since it may be double-buffered).
*/
declare const getLatestFiber: (fiber: Fiber) => Fiber;
type RenderHandler = <S>(fiber: Fiber, phase: RenderPhase, state?: S) => unknown;
type RenderPhase = "mount" | "unmount" | "update";
declare const setFiberId: (fiber: Fiber, id?: number) => void;
declare const getFiberId: (fiber: Fiber) => number;
/**
* Creates a fiber visitor function. Must pass a fiber root and a render handler.
* @example
* traverseRenderedFibers(root, (fiber, phase) => {
* console.log(phase)
* })
*/
declare const traverseRenderedFibers: (root: FiberRoot, onRender: RenderHandler) => void;
declare const overrideProps: (fiber: Fiber, partialValue: Record<string, unknown>) => void;
declare const overrideHookState: (fiber: Fiber, id: number, partialValue: unknown) => void;
declare const overrideContext: (fiber: Fiber, contextType: unknown, partialValue: unknown) => void;
interface InstrumentationOptions {
name?: string;
onActive?: () => unknown;
onCommitFiberRoot?: (rendererID: number, root: FiberRoot, priority: number | void) => unknown;
onCommitFiberUnmount?: (rendererID: number, fiber: Fiber) => unknown;
onPostCommitFiberRoot?: (rendererID: number, root: FiberRoot) => unknown;
onScheduleFiberRoot?: (rendererID: number, root: FiberRoot, children: React.ReactNode) => unknown;
}
/**
* Instruments the DevTools hook. Each hook event is patched once and
* dispatches to a set of listeners, so multiple `instrument` calls compose
* without stacking patches. Returns an unsubscribe function that removes
* exactly the handlers this call registered.
* The returned function is also a `Disposable`, so it composes with other
* bippy subscriptions through `using`.
* @example
* const unsubscribe = instrument({
* onActive() {
* console.log('initialized');
* },
* onCommitFiberRoot(rendererID, root) {
* console.log('fiberRoot', root.current)
* },
* });
* unsubscribe();
*/
declare const instrument: (options: InstrumentationOptions) => Unsubscribe;
declare const getFiberFromHostInstance: <T>(hostInstance: T) => Fiber | null;
//#endregion
export { isValidFiber as $, TRANSITIONAL_ELEMENT_TYPE_SYMBOL_STRING as A, getLatestFiber as B, MemoComponentTag as C, SimpleMemoComponentTag as D, RenderPhase as E, didFiberRender as F, getType as G, getNearestHostFiber as H, getDisplayName as I, isCompositeFiber as J, hasMemoCache as K, getFiberFromHostInstance as L, _fiberRoots as M, detectReactBuildType as N, SuspenseComponentTag as O, didFiberCommit as P, isValidElement as Q, getFiberId as R, LegacyHiddenComponentTag as S, RenderHandler as T, getNearestHostFibers as U, getMutatedHostFibers as V, getTimings as W, isHostFiber as X, isFiber as Y, isInstrumentationActive as Z, HostRootTag as _, isRealReactDevtools as _t, ClassComponentTag as a, traverseFiber as at, InstrumentationOptions as b, safelyInstallRDTHook as bt, DEPRECATED_ASYNC_MODE_SYMBOL_STRING as c, traverseState as ct, ForwardRefTag as d, _renderers as dt, overrideContext as et, FragmentTag as f, getRDTHook as ft, HostPortalTag as g, isReactRefresh as gt, HostHoistableTag as h, isClientEnvironment as ht, CONCURRENT_MODE_SYMBOL_STRING as i, traverseContexts as it, ViewTransitionComponentTag as j, SuspenseListComponentTag as k, DehydratedSuspenseComponentTag as l, BIPPY_INSTRUMENTATION_STRING as lt, HostComponentTag as m, installRDTHook as mt, CONCURRENT_MODE_NUMBER as n, overrideProps as nt, ContextConsumerTag as o, traverseProps as ot, FunctionComponentTag as p, hasRDTHook as pt, instrument as q, CONCURRENT_MODE_SYMBOL_DESCRIPTION as r, setFiberId as rt, DEPRECATED_ASYNC_MODE_SYMBOL_DESCRIPTION as s, traverseRenderedFibers as st, ActivityComponentTag as t, overrideHookState as tt, ELEMENT_TYPE_SYMBOL_STRING as u, _onActiveListeners as ut, HostSingletonTag as v, onRendererInject as vt, OffscreenComponentTag as w, LazyComponentTag as x, version as xt, HostTextTag as y, patchRDTHook as yt, getFiberStack as z };

9
node_modules/bippy/dist/core.js generated vendored Normal file

File diff suppressed because one or more lines are too long

3
node_modules/bippy/dist/core2.d.cts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import { A as ReactRenderer, B as TextSelector, C as React$AbstractComponent, D as ReactPortal, E as ReactDevToolsGlobalHook, F as Selector, H as TransitionTracingCallbacks, I as ServerComponentInfo, L as Source, M as RendererRefreshUpdate, N as RoleSelector, O as ReactProvider, P as RootTag, R as SuspenseHydrationCallbacks, S as Props, T as ReactContext, U as TypeOfMode, V as Thenable, W as WorkTag, _ as Lanes, a as ContextDependency, b as OpaqueHandle, c as Effect, d as FiberRoot, f as Flags, g as LanePriority, h as HostConfig, i as ComponentSelector, j as RefObject, k as ReactProviderType, l as Family, m as HookType, n as toUnsubscribe, o as Dependencies, p as HasPseudoClassSelector, r as BundleType, s as DevToolsConfig, t as Unsubscribe, u as Fiber, v as MemoizedState, w as ReactConsumer, x as OpaqueRoot, y as MutableSource, z as TestNameSelector } from "./unsubscribe.cjs";
import { $ as isValidFiber, A as TRANSITIONAL_ELEMENT_TYPE_SYMBOL_STRING, B as getLatestFiber, C as MemoComponentTag, D as SimpleMemoComponentTag, E as RenderPhase, F as didFiberRender, G as getType, H as getNearestHostFiber, I as getDisplayName, J as isCompositeFiber, K as hasMemoCache, L as getFiberFromHostInstance, M as _fiberRoots, N as detectReactBuildType, O as SuspenseComponentTag, P as didFiberCommit, Q as isValidElement, R as getFiberId, S as LegacyHiddenComponentTag, T as RenderHandler, U as getNearestHostFibers, V as getMutatedHostFibers, W as getTimings, X as isHostFiber, Y as isFiber, Z as isInstrumentationActive, _ as HostRootTag, _t as isRealReactDevtools, a as ClassComponentTag, at as traverseFiber, b as InstrumentationOptions, bt as safelyInstallRDTHook, c as DEPRECATED_ASYNC_MODE_SYMBOL_STRING, ct as traverseState, d as ForwardRefTag, dt as _renderers, et as overrideContext, f as FragmentTag, ft as getRDTHook, g as HostPortalTag, gt as isReactRefresh, h as HostHoistableTag, ht as isClientEnvironment, i as CONCURRENT_MODE_SYMBOL_STRING, it as traverseContexts, j as ViewTransitionComponentTag, k as SuspenseListComponentTag, l as DehydratedSuspenseComponentTag, lt as BIPPY_INSTRUMENTATION_STRING, m as HostComponentTag, mt as installRDTHook, n as CONCURRENT_MODE_NUMBER, nt as overrideProps, o as ContextConsumerTag, ot as traverseProps, p as FunctionComponentTag, pt as hasRDTHook, q as instrument, r as CONCURRENT_MODE_SYMBOL_DESCRIPTION, rt as setFiberId, s as DEPRECATED_ASYNC_MODE_SYMBOL_DESCRIPTION, st as traverseRenderedFibers, t as ActivityComponentTag, tt as overrideHookState, u as ELEMENT_TYPE_SYMBOL_STRING, ut as _onActiveListeners, v as HostSingletonTag, vt as onRendererInject, w as OffscreenComponentTag, x as LazyComponentTag, xt as version, y as HostTextTag, yt as patchRDTHook, z as getFiberStack } from "./core.cjs";
export { ActivityComponentTag, BIPPY_INSTRUMENTATION_STRING, BundleType, CONCURRENT_MODE_NUMBER, CONCURRENT_MODE_SYMBOL_DESCRIPTION, CONCURRENT_MODE_SYMBOL_STRING, ClassComponentTag, ComponentSelector, ContextConsumerTag, ContextDependency, DEPRECATED_ASYNC_MODE_SYMBOL_DESCRIPTION, DEPRECATED_ASYNC_MODE_SYMBOL_STRING, DehydratedSuspenseComponentTag, Dependencies, DevToolsConfig, ELEMENT_TYPE_SYMBOL_STRING, Effect, Family, Fiber, FiberRoot, Flags, ForwardRefTag, FragmentTag, FunctionComponentTag, HasPseudoClassSelector, HookType, HostComponentTag, HostConfig, HostHoistableTag, HostPortalTag, HostRootTag, HostSingletonTag, HostTextTag, InstrumentationOptions, LanePriority, Lanes, LazyComponentTag, LegacyHiddenComponentTag, MemoComponentTag, MemoizedState, MutableSource, OffscreenComponentTag, OpaqueHandle, OpaqueRoot, Props, React$AbstractComponent, ReactConsumer, ReactContext, ReactDevToolsGlobalHook, ReactPortal, ReactProvider, ReactProviderType, ReactRenderer, RefObject, RenderHandler, RenderPhase, RendererRefreshUpdate, RoleSelector, RootTag, Selector, ServerComponentInfo, SimpleMemoComponentTag, Source, SuspenseComponentTag, SuspenseHydrationCallbacks, SuspenseListComponentTag, TRANSITIONAL_ELEMENT_TYPE_SYMBOL_STRING, TestNameSelector, TextSelector, Thenable, TransitionTracingCallbacks, TypeOfMode, Unsubscribe, ViewTransitionComponentTag, WorkTag, _fiberRoots, _onActiveListeners, _renderers, detectReactBuildType, didFiberCommit, didFiberRender, getDisplayName, getFiberFromHostInstance, getFiberId, getFiberStack, getLatestFiber, getMutatedHostFibers, getNearestHostFiber, getNearestHostFibers, getRDTHook, getTimings, getType, hasMemoCache, hasRDTHook, installRDTHook, instrument, isClientEnvironment, isCompositeFiber, isFiber, isHostFiber, isInstrumentationActive, isReactRefresh, isRealReactDevtools, isValidElement, isValidFiber, onRendererInject, overrideContext, overrideHookState, overrideProps, patchRDTHook, safelyInstallRDTHook, setFiberId, toUnsubscribe, traverseContexts, traverseFiber, traverseProps, traverseRenderedFibers, traverseState, version };

3
node_modules/bippy/dist/core2.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import { A as ReactRenderer, B as TextSelector, C as React$AbstractComponent, D as ReactPortal, E as ReactDevToolsGlobalHook, F as Selector, H as TransitionTracingCallbacks, I as ServerComponentInfo, L as Source, M as RendererRefreshUpdate, N as RoleSelector, O as ReactProvider, P as RootTag, R as SuspenseHydrationCallbacks, S as Props, T as ReactContext, U as TypeOfMode, V as Thenable, W as WorkTag, _ as Lanes, a as ContextDependency, b as OpaqueHandle, c as Effect, d as FiberRoot, f as Flags, g as LanePriority, h as HostConfig, i as ComponentSelector, j as RefObject, k as ReactProviderType, l as Family, m as HookType, n as toUnsubscribe, o as Dependencies, p as HasPseudoClassSelector, r as BundleType, s as DevToolsConfig, t as Unsubscribe, u as Fiber, v as MemoizedState, w as ReactConsumer, x as OpaqueRoot, y as MutableSource, z as TestNameSelector } from "./unsubscribe.js";
import { $ as isValidFiber, A as TRANSITIONAL_ELEMENT_TYPE_SYMBOL_STRING, B as getLatestFiber, C as MemoComponentTag, D as SimpleMemoComponentTag, E as RenderPhase, F as didFiberRender, G as getType, H as getNearestHostFiber, I as getDisplayName, J as isCompositeFiber, K as hasMemoCache, L as getFiberFromHostInstance, M as _fiberRoots, N as detectReactBuildType, O as SuspenseComponentTag, P as didFiberCommit, Q as isValidElement, R as getFiberId, S as LegacyHiddenComponentTag, T as RenderHandler, U as getNearestHostFibers, V as getMutatedHostFibers, W as getTimings, X as isHostFiber, Y as isFiber, Z as isInstrumentationActive, _ as HostRootTag, _t as isRealReactDevtools, a as ClassComponentTag, at as traverseFiber, b as InstrumentationOptions, bt as safelyInstallRDTHook, c as DEPRECATED_ASYNC_MODE_SYMBOL_STRING, ct as traverseState, d as ForwardRefTag, dt as _renderers, et as overrideContext, f as FragmentTag, ft as getRDTHook, g as HostPortalTag, gt as isReactRefresh, h as HostHoistableTag, ht as isClientEnvironment, i as CONCURRENT_MODE_SYMBOL_STRING, it as traverseContexts, j as ViewTransitionComponentTag, k as SuspenseListComponentTag, l as DehydratedSuspenseComponentTag, lt as BIPPY_INSTRUMENTATION_STRING, m as HostComponentTag, mt as installRDTHook, n as CONCURRENT_MODE_NUMBER, nt as overrideProps, o as ContextConsumerTag, ot as traverseProps, p as FunctionComponentTag, pt as hasRDTHook, q as instrument, r as CONCURRENT_MODE_SYMBOL_DESCRIPTION, rt as setFiberId, s as DEPRECATED_ASYNC_MODE_SYMBOL_DESCRIPTION, st as traverseRenderedFibers, t as ActivityComponentTag, tt as overrideHookState, u as ELEMENT_TYPE_SYMBOL_STRING, ut as _onActiveListeners, v as HostSingletonTag, vt as onRendererInject, w as OffscreenComponentTag, x as LazyComponentTag, xt as version, y as HostTextTag, yt as patchRDTHook, z as getFiberStack } from "./core.js";
export { ActivityComponentTag, BIPPY_INSTRUMENTATION_STRING, BundleType, CONCURRENT_MODE_NUMBER, CONCURRENT_MODE_SYMBOL_DESCRIPTION, CONCURRENT_MODE_SYMBOL_STRING, ClassComponentTag, ComponentSelector, ContextConsumerTag, ContextDependency, DEPRECATED_ASYNC_MODE_SYMBOL_DESCRIPTION, DEPRECATED_ASYNC_MODE_SYMBOL_STRING, DehydratedSuspenseComponentTag, Dependencies, DevToolsConfig, ELEMENT_TYPE_SYMBOL_STRING, Effect, Family, Fiber, FiberRoot, Flags, ForwardRefTag, FragmentTag, FunctionComponentTag, HasPseudoClassSelector, HookType, HostComponentTag, HostConfig, HostHoistableTag, HostPortalTag, HostRootTag, HostSingletonTag, HostTextTag, InstrumentationOptions, LanePriority, Lanes, LazyComponentTag, LegacyHiddenComponentTag, MemoComponentTag, MemoizedState, MutableSource, OffscreenComponentTag, OpaqueHandle, OpaqueRoot, Props, React$AbstractComponent, ReactConsumer, ReactContext, ReactDevToolsGlobalHook, ReactPortal, ReactProvider, ReactProviderType, ReactRenderer, RefObject, RenderHandler, RenderPhase, RendererRefreshUpdate, RoleSelector, RootTag, Selector, ServerComponentInfo, SimpleMemoComponentTag, Source, SuspenseComponentTag, SuspenseHydrationCallbacks, SuspenseListComponentTag, TRANSITIONAL_ELEMENT_TYPE_SYMBOL_STRING, TestNameSelector, TextSelector, Thenable, TransitionTracingCallbacks, TypeOfMode, Unsubscribe, ViewTransitionComponentTag, WorkTag, _fiberRoots, _onActiveListeners, _renderers, detectReactBuildType, didFiberCommit, didFiberRender, getDisplayName, getFiberFromHostInstance, getFiberId, getFiberStack, getLatestFiber, getMutatedHostFibers, getNearestHostFiber, getNearestHostFibers, getRDTHook, getTimings, getType, hasMemoCache, hasRDTHook, installRDTHook, instrument, isClientEnvironment, isCompositeFiber, isFiber, isHostFiber, isInstrumentationActive, isReactRefresh, isRealReactDevtools, isValidElement, isValidFiber, onRendererInject, overrideContext, overrideHookState, overrideProps, patchRDTHook, safelyInstallRDTHook, setFiberId, toUnsubscribe, traverseContexts, traverseFiber, traverseProps, traverseRenderedFibers, traverseState, version };

19
node_modules/bippy/dist/get-source.cjs generated vendored Normal file
View File

@@ -0,0 +1,19 @@
/**
* @license bippy
*
* Copyright (c) Aiden Bai
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const e=require(`./rdt-hook.cjs`),t=require(`./core.cjs`),n=/^[a-zA-Z][a-zA-Z\d+\-.]*:/,r=[`rsc://`,`file:///`,`webpack-internal://`,`webpack://`,`node:`,`turbopack://`,`metro://`,`/app-pages-browser/`,`/(app-pages-browser)/`],i=[`rsc://`,`about://React/`],a=[`<anonymous>`,`eval`,``],o=/\.(jsx|tsx|ts|js)$/,s=/(\.min|bundle|chunk|vendor|vendors|runtime|polyfill|polyfills)\.(js|mjs|cjs)$|(chunk|bundle|vendor|vendors|runtime|polyfill|polyfills|framework|app|main|index)[-_.][A-Za-z0-9_-]{4,}\.(js|mjs|cjs)$|[\da-f]{8,}\.(js|mjs|cjs)$|[-_.][\da-f]{20,}\.(js|mjs|cjs)$|\/dist\/|\/build\/|\/.next\/|\/out\/|\/node_modules\/|\.webpack\.|\.vite\.|\.turbopack\./i,c=/^\?[\w~.-]+(?:=[^&#]*)?(?:&[\w~.-]+(?:=[^&#]*)?)*$/,l=/\(at [^)]+\)$/,u=[`react_stack_bottom_frame`,`react-stack-bottom-frame`],d=/(^|@)\S+:\d+/,f=/^\s*at .*(\S+:\d+|\(native\))/m,ee=/^(eval@)?(\[native code\])?$/,p=(e,t)=>{if(t?.includeInElement!==!1){let n=e.split(`
`),r=[];for(let e of n)if(/^\s*at\s+/.test(e)){let t=g(e,void 0)[0];t&&r.push(t)}else if(/^\s*in\s+/.test(e)){let t=e.replace(/^\s*in\s+/,``).replace(/\s*\(at .*\)$/,``);r.push({functionName:t,source:e})}else if(e.match(d)){let t=_(e,void 0)[0];t&&r.push(t)}return h(r,t)}return e.match(f)?g(e,t):_(e,t)},m=e=>{if(!e.includes(`:`))return[e,void 0,void 0];let t=e.startsWith(`(`)&&/:\d+\)$/.test(e)?e.slice(1,-1):e,n=/(.+?)(?::(\d+))?(?::(\d+))?$/.exec(t);return n?[n[1],n[2]||void 0,n[3]||void 0]:[t,void 0,void 0]},h=(e,t)=>t&&t.slice!=null?Array.isArray(t.slice)?e.slice(t.slice[0],t.slice[1]):e.slice(0,t.slice):e,g=(e,t)=>h(e.split(`
`).filter(e=>!!e.match(f)),t).map(e=>{let t=e;t.includes(`(eval `)&&(t=t.replace(/eval code/g,`eval`).replace(/(\(eval at [^()]*)|(,.*$)/g,``));let n=t.replace(/^\s+/,``).replace(/\(eval code/g,`(`).replace(/^.*?\s+/,``),r=n.match(/ (\(.+\)$)/);n=r?n.replace(r[0],``):n;let i=m(r?r[1]:n);return{functionName:r&&n||void 0,fileName:[`eval`,`<anonymous>`].includes(i[0])?void 0:i[0],lineNumber:i[1]?+i[1]:void 0,columnNumber:i[2]?+i[2]:void 0,source:t}}),_=(e,t)=>h(e.split(`
`).filter(e=>!e.match(ee)),t).map(e=>{let t=e;if(t.includes(` > eval`)&&(t=t.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g,`:$1`)),!t.includes(`@`)&&!t.includes(`:`))return{functionName:t};{let e=/(([^\n\r"\u2028\u2029]*".[^\n\r"\u2028\u2029]*"[^\n\r@\u2028\u2029]*(?:@[^\n\r"\u2028\u2029]*"[^\n\r@\u2028\u2029]*)*(?:[\n\r\u2028\u2029][^@]*)?)?[^@]*)@/,n=t.match(e),r=n&&n[1]?n[1]:void 0,i=m(t.replace(e,``));return{functionName:r,fileName:i[0],lineNumber:i[1]?+i[1]:void 0,columnNumber:i[2]?+i[2]:void 0,source:t}}}),v=new WeakMap,y=e=>u.some(t=>e.includes(t)),te=e=>{let t=e.getFunctionName?.()??``;if(t)return t;let n=e.getTypeName?.()??``,r=e.getMethodName?.()??``;return n&&r?`${n}.${r}`:r},ne=e=>{let t=[];for(let n=1;n<e.length;n++){let r=e[n],i=te(r);if(y(i))return{frames:t,isTrusted:!0};if(r.isNative?.()){t.push({functionName:i||void 0});continue}let a=r.getScriptNameOrSourceURL?.()??``;!a&&r.isEval?.()&&(a=r.getEvalOrigin?.()??``),t.push({functionName:i&&i!==`<anonymous>`?i:void 0,fileName:a&&a!==`<anonymous>`?a:void 0,lineNumber:r.getLineNumber?.()??void 0,columnNumber:r.getColumnNumber?.()??void 0,enclosingLineNumber:r.getEnclosingLineNumber?.()??void 0,enclosingColumnNumber:r.getEnclosingColumnNumber?.()??void 0,source:` at ${r.toString()}`})}return{frames:t,isTrusted:!1}},re=e=>{let t=-1;for(let n of u)if(t=e.indexOf(n),t!==-1)break;return{frames:p(t===-1?e:e.slice(0,e.lastIndexOf(`
`,t))).slice(1),isTrusted:t!==-1}},b=e=>{let t=v.get(e);if(t)return t;let n=null,r=(e,t)=>{n=ne(t);let r=`${e.name||`Error`}: ${e.message||``}`;for(let e of t)r+=`\n at ${e.toString()}`;return r},i=Error.prepareStackTrace;Error.prepareStackTrace=r;let a;try{a=String(e.stack)}finally{Error.prepareStackTrace=i}let o=n??re(a);return v.set(e,o),o};var x=44,S=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`,ie=new Uint8Array(64),C=new Uint8Array(128);for(let e=0;e<S.length;e++){let t=S.charCodeAt(e);ie[e]=t,C[t]=e}function w(e,t){let n=0,r=0,i=0;do i=C[e.next()],n|=(i&31)<<r,r+=5;while(i&32);let a=n&1;return n>>>=1,a&&(n=-2147483648|-n),t+n}function T(e,t){return e.pos>=t?!1:e.peek()!==x}var ae=class{constructor(e){this.pos=0,this.buffer=e}next(){return this.buffer.charCodeAt(this.pos++)}peek(){return this.buffer.charCodeAt(this.pos)}indexOf(e){let{buffer:t,pos:n}=this,r=t.indexOf(e,n);return r===-1?t.length:r}};function E(e){let{length:t}=e,n=new ae(e),r=[],i=0,a=0,o=0,s=0,c=0;do{let e=n.indexOf(`;`),t=[],l=!0,u=0;for(i=0;n.pos<e;){let r;i=w(n,i),i<u&&(l=!1),u=i,T(n,e)?(a=w(n,a),o=w(n,o),s=w(n,s),T(n,e)?(c=w(n,c),r=[i,a,o,s,c]):r=[i,a,o,s]):r=[i],t.push(r),n.pos++}l||oe(t),r.push(t),n.pos=e+1}while(n.pos<=t);return r}function oe(e){e.sort(se)}function se(e,t){return e[0]-t[0]}const D=/^[a-zA-Z][a-zA-Z\d+\-.]*:/,O=/^data:application\/json[^,]+base64,/,ce=/(?:\/\/[@#][ \t]+sourceMappingURL=([^\s'"]+?)[ \t]*$)|(?:\/\*[@#][ \t]+sourceMappingURL=([^*]+?)[ \t]*(?:\*\/)[ \t]*$)/,k=new Map,A=new Map,j=(e,t,n,r,i)=>{if(n<0||n>=e.length)return null;let a=e[n];if(!a||a.length===0)return null;let o=null,s=0,c=a.length-1;for(;s<=c;){let e=s+c>>1;a[e][0]<=r?(o=a[e],s=e+1):c=e-1}if(!o||o.length<4)return null;let[,l,u,d]=o;if(l===void 0||u===void 0||d===void 0)return null;let f=t[l];return f?{columnNumber:d,fileName:f,lineNumber:u+1,isIgnoreListed:i?.has(l)??!1}:null},M=(e,t,n)=>{if(e.sections){let r=t-1,i=null;for(let t of e.sections)if(r>t.offset.line||r===t.offset.line&&n>=t.offset.column)i=t;else break;if(!i)return null;let a=r-i.offset.line,o=r===i.offset.line?n-i.offset.column:n;return j(i.map.mappings,i.map.sources,a,o,i.map.ignoredSourceIndices)}return j(e.mappings,e.sources,t-1,n,e.ignoredSourceIndices)},le=(e,t)=>{let n,r=t.length;for(;r>0&&!n;){let e=t.lastIndexOf(`
`,r-1)+1,i=t.slice(e,r).match(ce);i&&(n=i[1]||i[2]),r=e-1}if(!n)return null;let i=D.test(n);if(!(O.test(n)||i||n.startsWith(`/`))){let t=e.split(`/`);t[t.length-1]=n,n=t.join(`/`)}return n},N=e=>{let t=e.ignoreList??e.x_google_ignoreList;return Array.isArray(t)&&t.length>0?new Set(t):void 0},ue=e=>({file:e.file,ignoredSourceIndices:N(e),mappings:E(e.mappings),names:e.names,sourceRoot:e.sourceRoot,sources:e.sources,sourcesContent:e.sourcesContent,version:3}),de=e=>{let t=e.sections.map(({map:e,offset:t})=>({map:{...e,ignoredSourceIndices:N(e),mappings:E(e.mappings)},offset:t})),n=new Set;for(let e of t)for(let t of e.map.sources)n.add(t);return{file:e.file,mappings:[],names:[],sections:t,sourceRoot:void 0,sources:Array.from(n),sourcesContent:void 0,version:3}},P=e=>{if(!e)return!1;let t=e.trim();if(!t)return!1;let n=t.match(D);if(!n)return!0;let r=n[0].toLowerCase();return r===`http:`||r===`https:`},fe=async(e,t=fetch)=>{if(!P(e))return null;let n=await t(e);if(!n.ok)return null;let r=await n.text();if(!r)return null;let i=le(e,r);if(!i||!P(i)&&!O.test(i))return null;let a=await t(i);if(!a.ok)return null;try{let e=await a.json();return`sections`in e?de(e):ue(e)}catch{return null}},F=async(e,t=!0,n)=>{if(t&&k.has(e))return k.get(e)??null;let r=t?A.get(e):void 0;if(r)return(await r).sourceMap;let i=fe(e,n).then(e=>({sourceMap:e,isTransientFailure:!1}),()=>({sourceMap:null,isTransientFailure:!0}));t&&A.set(e,i);let{sourceMap:a,isTransientFailure:o}=await i;return t&&(A.delete(e),o||k.set(e,a)),a},I=async(e,t=!0,n)=>await Promise.all(e.map(async e=>{if(!e.fileName)return e;let r=await F(e.fileName,t,n);if(!r||typeof e.lineNumber!=`number`||typeof e.columnNumber!=`number`)return e;let i=M(r,e.lineNumber,e.columnNumber);return i?{...e,source:i.fileName&&e.source?e.source.replace(e.fileName,i.fileName):e.source,fileName:i.fileName,lineNumber:i.lineNumber,columnNumber:i.columnNumber,isIgnoreListed:i.isIgnoreListed,isSymbolicated:!0}:e})),L=e=>e._debugStack instanceof Error&&typeof e._debugStack?.stack==`string`,R=e=>typeof e.tag==`number`,z=e=>e._debugOwner,B=e=>{let n=null;if(t.traverseFiber(e,t=>{if(t===e)return!1;let r=t._debugOwner;return(r===e||e.alternate!==null&&r===e.alternate)&&t._debugStack instanceof Error?(n=t._debugStack,!0):!1}),!n)return null;let{frames:r,isTrusted:i}=b(n);if(!i)return null;for(let e=r.length-1;e>=0;e--){let t=r[e];if(t.fileName)return{...t,lineNumber:t.enclosingLineNumber||t.lineNumber,columnNumber:t.enclosingColumnNumber||t.columnNumber}}return null},V=()=>{let t=e.i();for(let n of[...Array.from(e.r),...Array.from(t.renderers.values())]){let e=n.currentDispatcherRef;if(e&&typeof e==`object`)return`H`in e?e.H:e.current}return null},H=t=>{for(let n of e.r){let e=n.currentDispatcherRef;e&&typeof e==`object`&&(`H`in e?e.H=t:e.current=t)}},U=e=>`\n in ${e}`,pe=(e,t)=>{let n=U(e);return t&&(n+=` (at ${t})`),n};let W=!1;const G=new WeakMap,K=(e,n)=>{if(!e||W)return``;let r=G.get(e);if(r!==void 0)return r;let i=Error.prepareStackTrace;Error.prepareStackTrace=void 0,W=!0;let a=V();H(null);let o=console.error,s=console.warn;console.error=()=>{},console.warn=()=>{};try{let r={DetermineComponentFrameRoot(){let t;try{if(n){let n=function(){throw Error()};if(Object.defineProperty(n.prototype,`props`,{set:function(){throw Error()}}),typeof Reflect==`object`&&Reflect.construct){try{Reflect.construct(n,[])}catch(e){t=e}Reflect.construct(e,[],n)}else{try{n.call()}catch(e){t=e}e.call(n.prototype)}}else{try{throw Error()}catch(e){t=e}let n=e();n&&typeof n.catch==`function`&&n.catch(()=>{})}}catch(e){if(e instanceof Error&&t instanceof Error&&typeof e.stack==`string`)return[e.stack,t.stack]}return[null,null]}};r.DetermineComponentFrameRoot.displayName=`DetermineComponentFrameRoot`,Object.getOwnPropertyDescriptor(r.DetermineComponentFrameRoot,`name`)?.configurable&&Object.defineProperty(r.DetermineComponentFrameRoot,`name`,{value:`DetermineComponentFrameRoot`});let[i,a]=r.DetermineComponentFrameRoot();if(i&&a){let n=i.split(`
`),r=a.split(`
`),o=0,s=0;for(;o<n.length&&!n[o].includes(`DetermineComponentFrameRoot`);)o++;for(;s<r.length&&!r[s].includes(`DetermineComponentFrameRoot`);)s++;if(o===n.length||s===r.length)for(o=n.length-1,s=r.length-1;o>=1&&s>=0&&n[o]!==r[s];)s--;for(;o>=1&&s>=0;o--,s--)if(n[o]!==r[s]){if(o!==1||s!==1)do if(o--,s--,s<0||n[o]!==r[s]){let r=`\n${n[o].replace(` at new `,` at `)}`,i=t.getDisplayName(e);return i&&r.includes(`<anonymous>`)&&(r=r.replace(`<anonymous>`,i)),G.set(e,r),r}while(o>=1&&s>=0);break}}}finally{W=!1,Error.prepareStackTrace=i,H(a),console.error=o,console.warn=s}let c=e?t.getDisplayName(e):``,l=c?U(c):``;return G.set(e,l),l},me=(e,t)=>{let n=e.tag,r=``;switch(n){case 28:r=U(`Activity`);break;case 1:r=K(e.type,!0);break;case 11:r=K(e.type.render,!1);break;case 0:case 15:r=K(e.type,!1);break;case 5:case 26:case 27:r=U(e.type);break;case 16:r=U(`Lazy`);break;case 13:r=e.child!==t&&t!==null?U(`Suspense Fallback`):U(`Suspense`);break;case 19:r=U(`SuspenseList`);break;case 30:r=U(`ViewTransition`);break;default:return``}return r},he=e=>{try{let t=``,n=e,r=null;do{t+=me(n,r);let e=n._debugInfo;if(e&&Array.isArray(e))for(let n=e.length-1;n>=0;n--){let r=e[n];typeof r.name==`string`&&(t+=pe(r.name,r.env))}r=n,n=n.return}while(n);return t}catch(e){return e instanceof Error?`\nError generating stack: ${e.message}\n${e.stack}`:``}},q=e=>{let t=Error.prepareStackTrace;Error.prepareStackTrace=void 0;let n=e;if(!n)return``;Error.prepareStackTrace=t,n.startsWith(`Error: react-stack-top-frame
`)&&(n=n.slice(29));let r=n.indexOf(`
`);r!==-1&&(n=n.slice(r+1));let i=Math.max(n.indexOf(`react_stack_bottom_frame`),n.indexOf(`react-stack-bottom-frame`));if(i!==-1&&(i=n.lastIndexOf(`
`,i)),i!==-1)n=n.slice(0,i);else return``;return n},ge=e=>!!(e.functionName&&e.fileName&&J(e.fileName)),_e=(e,t)=>e.fileName===t.fileName&&e.lineNumber===t.lineNumber&&e.columnNumber===t.columnNumber,ve=e=>{let t=new Map;for(let n of e)for(let e of n.stackFrames){if(!ge(e))continue;let n=e.functionName,r=t.get(n)??[];r.some(t=>_e(t,e))||(r.push(e),t.set(n,r))}return t},ye=(e,t,n)=>{if(!e.functionName)return{...e,isServer:!0};let r=t.get(e.functionName);if(!r||r.length===0)return{...e,isServer:!0};let i=n.get(e.functionName)??0,a=r[i%r.length];return n.set(e.functionName,i+1),{...e,isServer:!0,fileName:a.fileName,lineNumber:a.lineNumber,columnNumber:a.columnNumber,source:e.source?.replace(`(at Server)`,`(${a.fileName}:${a.lineNumber}:${a.columnNumber})`)}},J=e=>i.some(t=>e.startsWith(t)),be=e=>!e.isServer&&e.fileName&&J(e.fileName)?{...e,isServer:!0}:e,xe=e=>{let t=[],n=e;for(;n;)if(R(n)){let e=n;if(n=z(e),n&&L(e)){let{frames:n,isTrusted:r}=b(e._debugStack);if(r)for(let e of n)t.push(be(e))}}else{let e=n;if(n=e.owner,n&&e.debugStack instanceof Error)for(let n of b(e.debugStack).frames)t.push({...n,isServer:!0})}return t},Se=e=>{let n=[];return t.traverseFiber(e,e=>{if(!L(e))return;let r=typeof e.type==`string`?e.type:t.getDisplayName(e.type)||`<anonymous>`;n.push({componentName:r,stackFrames:p(q(e._debugStack?.stack))})},!0),n},Y=async(e,t=!0,n)=>{let r=Se(e),i=p(he(e)),a=ve(r),o=new Map;return I(i.map(e=>(e.source?.includes(`(at Server)`)??!1)||e.source!=null&&l.test(e.source)?ye(e,a,o):e).filter((e,t,n)=>{if(t===0)return!0;let r=n[t-1];return e.functionName!==r.functionName}),t,n)},Ce=e=>!!e.fileName&&!e.isIgnoreListed,X=async(e,n=!0,r)=>{let i=xe(e);if(i.length>0){let a=B(e)??{};a.functionName=t.getDisplayName(e.type)??a.functionName;let o=await I([a,...i],n,r);if(o.some((e,t)=>t>0&&Ce(e)))return o}return Y(e,n,r)},we=e=>{let t=e._debugSource;return t?typeof t==`object`&&!!t&&`fileName`in t&&typeof t.fileName==`string`&&`lineNumber`in t&&typeof t.lineNumber==`number`:!1},Z=e=>e.fileName?{fileName:e.fileName,lineNumber:e.lineNumber,columnNumber:e.columnNumber,functionName:e.functionName}:null,Te=e=>{if(!L(e))return null;let{frames:t,isTrusted:n}=b(e._debugStack);if(!n)return null;for(let e of t)if(e.fileName)return e;return null},Ee=async(e,t=!0,n)=>{if(we(e))return e._debugSource||null;let r=Te(e)??B(e);if(r){let[e]=await I([r],t,n),i=Z(e);if(i)return i}let i=await Y(e,t,n);for(let e of i)if(e.fileName)return Z(e);return null},Q=e=>e.split(`/`).filter(Boolean).length,De=e=>e.split(`/`).filter(Boolean)[0]??null,Oe=e=>{let t=e.indexOf(`/`,1);if(t===-1||Q(e.slice(0,t))!==1)return e;let n=e.slice(t);if(!o.test(n)||Q(n)<2)return e;let r=De(n);return!r||r.startsWith(`@`)||r.length>4?e:n},$=e=>{if(!e||a.some(t=>t===e))return``;let t=e,i=t.startsWith(`http://`)||t.startsWith(`https://`);if(i)try{t=new URL(t).pathname}catch{}if(i&&(t=Oe(t)),t.startsWith(`about://React/`)){let e=t.slice(14),n=e.indexOf(`/`),r=e.indexOf(`:`);t=n!==-1&&(r===-1||n<r)?e.slice(n+1):e}let o=!0;for(;o;){o=!1;for(let e of r)if(t.startsWith(e)){t=t.slice(e.length),e===`file:///`&&(t=`/${t.replace(/^\/+/,``)}`),o=!0;break}}if(n.test(t)){let e=t.match(n);e&&(t=t.slice(e[0].length))}if(t.startsWith(`//`)){let e=t.indexOf(`/`,2);t=e===-1?``:t.slice(e)}let s=t.indexOf(`?`);if(s!==-1){let e=t.slice(s);c.test(e)&&(t=t.slice(0,s))}return t},ke=e=>{let t=$(e);return!(!t||!o.test(t)||s.test(t))};Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return X}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return M}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return q}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return F}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return ke}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return Y}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return $}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return L}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return Ee}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return I}});

19
node_modules/bippy/dist/get-source.js generated vendored Normal file
View File

@@ -0,0 +1,19 @@
/**
* @license bippy
*
* Copyright (c) Aiden Bai
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import{i as e,r as t}from"./rdt-hook.js";import{getDisplayName as n,traverseFiber as r}from"./core.js";const i=/^[a-zA-Z][a-zA-Z\d+\-.]*:/,a=[`rsc://`,`file:///`,`webpack-internal://`,`webpack://`,`node:`,`turbopack://`,`metro://`,`/app-pages-browser/`,`/(app-pages-browser)/`],o=[`rsc://`,`about://React/`],s=[`<anonymous>`,`eval`,``],c=/\.(jsx|tsx|ts|js)$/,l=/(\.min|bundle|chunk|vendor|vendors|runtime|polyfill|polyfills)\.(js|mjs|cjs)$|(chunk|bundle|vendor|vendors|runtime|polyfill|polyfills|framework|app|main|index)[-_.][A-Za-z0-9_-]{4,}\.(js|mjs|cjs)$|[\da-f]{8,}\.(js|mjs|cjs)$|[-_.][\da-f]{20,}\.(js|mjs|cjs)$|\/dist\/|\/build\/|\/.next\/|\/out\/|\/node_modules\/|\.webpack\.|\.vite\.|\.turbopack\./i,u=/^\?[\w~.-]+(?:=[^&#]*)?(?:&[\w~.-]+(?:=[^&#]*)?)*$/,d=/\(at [^)]+\)$/,f=[`react_stack_bottom_frame`,`react-stack-bottom-frame`],ee=/(^|@)\S+:\d+/,p=/^\s*at .*(\S+:\d+|\(native\))/m,te=/^(eval@)?(\[native code\])?$/,m=(e,t)=>{if(t?.includeInElement!==!1){let n=e.split(`
`),r=[];for(let e of n)if(/^\s*at\s+/.test(e)){let t=_(e,void 0)[0];t&&r.push(t)}else if(/^\s*in\s+/.test(e)){let t=e.replace(/^\s*in\s+/,``).replace(/\s*\(at .*\)$/,``);r.push({functionName:t,source:e})}else if(e.match(ee)){let t=v(e,void 0)[0];t&&r.push(t)}return g(r,t)}return e.match(p)?_(e,t):v(e,t)},h=e=>{if(!e.includes(`:`))return[e,void 0,void 0];let t=e.startsWith(`(`)&&/:\d+\)$/.test(e)?e.slice(1,-1):e,n=/(.+?)(?::(\d+))?(?::(\d+))?$/.exec(t);return n?[n[1],n[2]||void 0,n[3]||void 0]:[t,void 0,void 0]},g=(e,t)=>t&&t.slice!=null?Array.isArray(t.slice)?e.slice(t.slice[0],t.slice[1]):e.slice(0,t.slice):e,_=(e,t)=>g(e.split(`
`).filter(e=>!!e.match(p)),t).map(e=>{let t=e;t.includes(`(eval `)&&(t=t.replace(/eval code/g,`eval`).replace(/(\(eval at [^()]*)|(,.*$)/g,``));let n=t.replace(/^\s+/,``).replace(/\(eval code/g,`(`).replace(/^.*?\s+/,``),r=n.match(/ (\(.+\)$)/);n=r?n.replace(r[0],``):n;let i=h(r?r[1]:n);return{functionName:r&&n||void 0,fileName:[`eval`,`<anonymous>`].includes(i[0])?void 0:i[0],lineNumber:i[1]?+i[1]:void 0,columnNumber:i[2]?+i[2]:void 0,source:t}}),v=(e,t)=>g(e.split(`
`).filter(e=>!e.match(te)),t).map(e=>{let t=e;if(t.includes(` > eval`)&&(t=t.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g,`:$1`)),!t.includes(`@`)&&!t.includes(`:`))return{functionName:t};{let e=/(([^\n\r"\u2028\u2029]*".[^\n\r"\u2028\u2029]*"[^\n\r@\u2028\u2029]*(?:@[^\n\r"\u2028\u2029]*"[^\n\r@\u2028\u2029]*)*(?:[\n\r\u2028\u2029][^@]*)?)?[^@]*)@/,n=t.match(e),r=n&&n[1]?n[1]:void 0,i=h(t.replace(e,``));return{functionName:r,fileName:i[0],lineNumber:i[1]?+i[1]:void 0,columnNumber:i[2]?+i[2]:void 0,source:t}}}),y=new WeakMap,ne=e=>f.some(t=>e.includes(t)),re=e=>{let t=e.getFunctionName?.()??``;if(t)return t;let n=e.getTypeName?.()??``,r=e.getMethodName?.()??``;return n&&r?`${n}.${r}`:r},ie=e=>{let t=[];for(let n=1;n<e.length;n++){let r=e[n],i=re(r);if(ne(i))return{frames:t,isTrusted:!0};if(r.isNative?.()){t.push({functionName:i||void 0});continue}let a=r.getScriptNameOrSourceURL?.()??``;!a&&r.isEval?.()&&(a=r.getEvalOrigin?.()??``),t.push({functionName:i&&i!==`<anonymous>`?i:void 0,fileName:a&&a!==`<anonymous>`?a:void 0,lineNumber:r.getLineNumber?.()??void 0,columnNumber:r.getColumnNumber?.()??void 0,enclosingLineNumber:r.getEnclosingLineNumber?.()??void 0,enclosingColumnNumber:r.getEnclosingColumnNumber?.()??void 0,source:` at ${r.toString()}`})}return{frames:t,isTrusted:!1}},ae=e=>{let t=-1;for(let n of f)if(t=e.indexOf(n),t!==-1)break;return{frames:m(t===-1?e:e.slice(0,e.lastIndexOf(`
`,t))).slice(1),isTrusted:t!==-1}},b=e=>{let t=y.get(e);if(t)return t;let n=null,r=(e,t)=>{n=ie(t);let r=`${e.name||`Error`}: ${e.message||``}`;for(let e of t)r+=`\n at ${e.toString()}`;return r},i=Error.prepareStackTrace;Error.prepareStackTrace=r;let a;try{a=String(e.stack)}finally{Error.prepareStackTrace=i}let o=n??ae(a);return y.set(e,o),o};var oe=44,x=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`,se=new Uint8Array(64),S=new Uint8Array(128);for(let e=0;e<x.length;e++){let t=x.charCodeAt(e);se[e]=t,S[t]=e}function C(e,t){let n=0,r=0,i=0;do i=S[e.next()],n|=(i&31)<<r,r+=5;while(i&32);let a=n&1;return n>>>=1,a&&(n=-2147483648|-n),t+n}function w(e,t){return e.pos>=t?!1:e.peek()!==oe}var ce=class{constructor(e){this.pos=0,this.buffer=e}next(){return this.buffer.charCodeAt(this.pos++)}peek(){return this.buffer.charCodeAt(this.pos)}indexOf(e){let{buffer:t,pos:n}=this,r=t.indexOf(e,n);return r===-1?t.length:r}};function T(e){let{length:t}=e,n=new ce(e),r=[],i=0,a=0,o=0,s=0,c=0;do{let e=n.indexOf(`;`),t=[],l=!0,u=0;for(i=0;n.pos<e;){let r;i=C(n,i),i<u&&(l=!1),u=i,w(n,e)?(a=C(n,a),o=C(n,o),s=C(n,s),w(n,e)?(c=C(n,c),r=[i,a,o,s,c]):r=[i,a,o,s]):r=[i],t.push(r),n.pos++}l||E(t),r.push(t),n.pos=e+1}while(n.pos<=t);return r}function E(e){e.sort(D)}function D(e,t){return e[0]-t[0]}const O=/^[a-zA-Z][a-zA-Z\d+\-.]*:/,k=/^data:application\/json[^,]+base64,/,le=/(?:\/\/[@#][ \t]+sourceMappingURL=([^\s'"]+?)[ \t]*$)|(?:\/\*[@#][ \t]+sourceMappingURL=([^*]+?)[ \t]*(?:\*\/)[ \t]*$)/,A=new Map,j=new Map,M=(e,t,n,r,i)=>{if(n<0||n>=e.length)return null;let a=e[n];if(!a||a.length===0)return null;let o=null,s=0,c=a.length-1;for(;s<=c;){let e=s+c>>1;a[e][0]<=r?(o=a[e],s=e+1):c=e-1}if(!o||o.length<4)return null;let[,l,u,d]=o;if(l===void 0||u===void 0||d===void 0)return null;let f=t[l];return f?{columnNumber:d,fileName:f,lineNumber:u+1,isIgnoreListed:i?.has(l)??!1}:null},N=(e,t,n)=>{if(e.sections){let r=t-1,i=null;for(let t of e.sections)if(r>t.offset.line||r===t.offset.line&&n>=t.offset.column)i=t;else break;if(!i)return null;let a=r-i.offset.line,o=r===i.offset.line?n-i.offset.column:n;return M(i.map.mappings,i.map.sources,a,o,i.map.ignoredSourceIndices)}return M(e.mappings,e.sources,t-1,n,e.ignoredSourceIndices)},ue=(e,t)=>{let n,r=t.length;for(;r>0&&!n;){let e=t.lastIndexOf(`
`,r-1)+1,i=t.slice(e,r).match(le);i&&(n=i[1]||i[2]),r=e-1}if(!n)return null;let i=O.test(n);if(!(k.test(n)||i||n.startsWith(`/`))){let t=e.split(`/`);t[t.length-1]=n,n=t.join(`/`)}return n},P=e=>{let t=e.ignoreList??e.x_google_ignoreList;return Array.isArray(t)&&t.length>0?new Set(t):void 0},de=e=>({file:e.file,ignoredSourceIndices:P(e),mappings:T(e.mappings),names:e.names,sourceRoot:e.sourceRoot,sources:e.sources,sourcesContent:e.sourcesContent,version:3}),fe=e=>{let t=e.sections.map(({map:e,offset:t})=>({map:{...e,ignoredSourceIndices:P(e),mappings:T(e.mappings)},offset:t})),n=new Set;for(let e of t)for(let t of e.map.sources)n.add(t);return{file:e.file,mappings:[],names:[],sections:t,sourceRoot:void 0,sources:Array.from(n),sourcesContent:void 0,version:3}},F=e=>{if(!e)return!1;let t=e.trim();if(!t)return!1;let n=t.match(O);if(!n)return!0;let r=n[0].toLowerCase();return r===`http:`||r===`https:`},pe=async(e,t=fetch)=>{if(!F(e))return null;let n=await t(e);if(!n.ok)return null;let r=await n.text();if(!r)return null;let i=ue(e,r);if(!i||!F(i)&&!k.test(i))return null;let a=await t(i);if(!a.ok)return null;try{let e=await a.json();return`sections`in e?fe(e):de(e)}catch{return null}},I=async(e,t=!0,n)=>{if(t&&A.has(e))return A.get(e)??null;let r=t?j.get(e):void 0;if(r)return(await r).sourceMap;let i=pe(e,n).then(e=>({sourceMap:e,isTransientFailure:!1}),()=>({sourceMap:null,isTransientFailure:!0}));t&&j.set(e,i);let{sourceMap:a,isTransientFailure:o}=await i;return t&&(j.delete(e),o||A.set(e,a)),a},L=async(e,t=!0,n)=>await Promise.all(e.map(async e=>{if(!e.fileName)return e;let r=await I(e.fileName,t,n);if(!r||typeof e.lineNumber!=`number`||typeof e.columnNumber!=`number`)return e;let i=N(r,e.lineNumber,e.columnNumber);return i?{...e,source:i.fileName&&e.source?e.source.replace(e.fileName,i.fileName):e.source,fileName:i.fileName,lineNumber:i.lineNumber,columnNumber:i.columnNumber,isIgnoreListed:i.isIgnoreListed,isSymbolicated:!0}:e})),R=e=>e._debugStack instanceof Error&&typeof e._debugStack?.stack==`string`,z=e=>typeof e.tag==`number`,B=e=>e._debugOwner,V=e=>{let t=null;if(r(e,n=>{if(n===e)return!1;let r=n._debugOwner;return(r===e||e.alternate!==null&&r===e.alternate)&&n._debugStack instanceof Error?(t=n._debugStack,!0):!1}),!t)return null;let{frames:n,isTrusted:i}=b(t);if(!i)return null;for(let e=n.length-1;e>=0;e--){let t=n[e];if(t.fileName)return{...t,lineNumber:t.enclosingLineNumber||t.lineNumber,columnNumber:t.enclosingColumnNumber||t.columnNumber}}return null},me=()=>{let n=e();for(let e of[...Array.from(t),...Array.from(n.renderers.values())]){let t=e.currentDispatcherRef;if(t&&typeof t==`object`)return`H`in t?t.H:t.current}return null},H=e=>{for(let n of t){let t=n.currentDispatcherRef;t&&typeof t==`object`&&(`H`in t?t.H=e:t.current=e)}},U=e=>`\n in ${e}`,he=(e,t)=>{let n=U(e);return t&&(n+=` (at ${t})`),n};let W=!1;const G=new WeakMap,K=(e,t)=>{if(!e||W)return``;let r=G.get(e);if(r!==void 0)return r;let i=Error.prepareStackTrace;Error.prepareStackTrace=void 0,W=!0;let a=me();H(null);let o=console.error,s=console.warn;console.error=()=>{},console.warn=()=>{};try{let r={DetermineComponentFrameRoot(){let n;try{if(t){let t=function(){throw Error()};if(Object.defineProperty(t.prototype,`props`,{set:function(){throw Error()}}),typeof Reflect==`object`&&Reflect.construct){try{Reflect.construct(t,[])}catch(e){n=e}Reflect.construct(e,[],t)}else{try{t.call()}catch(e){n=e}e.call(t.prototype)}}else{try{throw Error()}catch(e){n=e}let t=e();t&&typeof t.catch==`function`&&t.catch(()=>{})}}catch(e){if(e instanceof Error&&n instanceof Error&&typeof e.stack==`string`)return[e.stack,n.stack]}return[null,null]}};r.DetermineComponentFrameRoot.displayName=`DetermineComponentFrameRoot`,Object.getOwnPropertyDescriptor(r.DetermineComponentFrameRoot,`name`)?.configurable&&Object.defineProperty(r.DetermineComponentFrameRoot,`name`,{value:`DetermineComponentFrameRoot`});let[i,a]=r.DetermineComponentFrameRoot();if(i&&a){let t=i.split(`
`),r=a.split(`
`),o=0,s=0;for(;o<t.length&&!t[o].includes(`DetermineComponentFrameRoot`);)o++;for(;s<r.length&&!r[s].includes(`DetermineComponentFrameRoot`);)s++;if(o===t.length||s===r.length)for(o=t.length-1,s=r.length-1;o>=1&&s>=0&&t[o]!==r[s];)s--;for(;o>=1&&s>=0;o--,s--)if(t[o]!==r[s]){if(o!==1||s!==1)do if(o--,s--,s<0||t[o]!==r[s]){let r=`\n${t[o].replace(` at new `,` at `)}`,i=n(e);return i&&r.includes(`<anonymous>`)&&(r=r.replace(`<anonymous>`,i)),G.set(e,r),r}while(o>=1&&s>=0);break}}}finally{W=!1,Error.prepareStackTrace=i,H(a),console.error=o,console.warn=s}let c=e?n(e):``,l=c?U(c):``;return G.set(e,l),l},ge=(e,t)=>{let n=e.tag,r=``;switch(n){case 28:r=U(`Activity`);break;case 1:r=K(e.type,!0);break;case 11:r=K(e.type.render,!1);break;case 0:case 15:r=K(e.type,!1);break;case 5:case 26:case 27:r=U(e.type);break;case 16:r=U(`Lazy`);break;case 13:r=e.child!==t&&t!==null?U(`Suspense Fallback`):U(`Suspense`);break;case 19:r=U(`SuspenseList`);break;case 30:r=U(`ViewTransition`);break;default:return``}return r},_e=e=>{try{let t=``,n=e,r=null;do{t+=ge(n,r);let e=n._debugInfo;if(e&&Array.isArray(e))for(let n=e.length-1;n>=0;n--){let r=e[n];typeof r.name==`string`&&(t+=he(r.name,r.env))}r=n,n=n.return}while(n);return t}catch(e){return e instanceof Error?`\nError generating stack: ${e.message}\n${e.stack}`:``}},q=e=>{let t=Error.prepareStackTrace;Error.prepareStackTrace=void 0;let n=e;if(!n)return``;Error.prepareStackTrace=t,n.startsWith(`Error: react-stack-top-frame
`)&&(n=n.slice(29));let r=n.indexOf(`
`);r!==-1&&(n=n.slice(r+1));let i=Math.max(n.indexOf(`react_stack_bottom_frame`),n.indexOf(`react-stack-bottom-frame`));if(i!==-1&&(i=n.lastIndexOf(`
`,i)),i!==-1)n=n.slice(0,i);else return``;return n},ve=e=>!!(e.functionName&&e.fileName&&J(e.fileName)),ye=(e,t)=>e.fileName===t.fileName&&e.lineNumber===t.lineNumber&&e.columnNumber===t.columnNumber,be=e=>{let t=new Map;for(let n of e)for(let e of n.stackFrames){if(!ve(e))continue;let n=e.functionName,r=t.get(n)??[];r.some(t=>ye(t,e))||(r.push(e),t.set(n,r))}return t},xe=(e,t,n)=>{if(!e.functionName)return{...e,isServer:!0};let r=t.get(e.functionName);if(!r||r.length===0)return{...e,isServer:!0};let i=n.get(e.functionName)??0,a=r[i%r.length];return n.set(e.functionName,i+1),{...e,isServer:!0,fileName:a.fileName,lineNumber:a.lineNumber,columnNumber:a.columnNumber,source:e.source?.replace(`(at Server)`,`(${a.fileName}:${a.lineNumber}:${a.columnNumber})`)}},J=e=>o.some(t=>e.startsWith(t)),Se=e=>!e.isServer&&e.fileName&&J(e.fileName)?{...e,isServer:!0}:e,Ce=e=>{let t=[],n=e;for(;n;)if(z(n)){let e=n;if(n=B(e),n&&R(e)){let{frames:n,isTrusted:r}=b(e._debugStack);if(r)for(let e of n)t.push(Se(e))}}else{let e=n;if(n=e.owner,n&&e.debugStack instanceof Error)for(let n of b(e.debugStack).frames)t.push({...n,isServer:!0})}return t},we=e=>{let t=[];return r(e,e=>{if(!R(e))return;let r=typeof e.type==`string`?e.type:n(e.type)||`<anonymous>`;t.push({componentName:r,stackFrames:m(q(e._debugStack?.stack))})},!0),t},Y=async(e,t=!0,n)=>{let r=we(e),i=m(_e(e)),a=be(r),o=new Map;return L(i.map(e=>(e.source?.includes(`(at Server)`)??!1)||e.source!=null&&d.test(e.source)?xe(e,a,o):e).filter((e,t,n)=>{if(t===0)return!0;let r=n[t-1];return e.functionName!==r.functionName}),t,n)},Te=e=>!!e.fileName&&!e.isIgnoreListed,X=async(e,t=!0,r)=>{let i=Ce(e);if(i.length>0){let a=V(e)??{};a.functionName=n(e.type)??a.functionName;let o=await L([a,...i],t,r);if(o.some((e,t)=>t>0&&Te(e)))return o}return Y(e,t,r)},Ee=e=>{let t=e._debugSource;return t?typeof t==`object`&&!!t&&`fileName`in t&&typeof t.fileName==`string`&&`lineNumber`in t&&typeof t.lineNumber==`number`:!1},Z=e=>e.fileName?{fileName:e.fileName,lineNumber:e.lineNumber,columnNumber:e.columnNumber,functionName:e.functionName}:null,De=e=>{if(!R(e))return null;let{frames:t,isTrusted:n}=b(e._debugStack);if(!n)return null;for(let e of t)if(e.fileName)return e;return null},Oe=async(e,t=!0,n)=>{if(Ee(e))return e._debugSource||null;let r=De(e)??V(e);if(r){let[e]=await L([r],t,n),i=Z(e);if(i)return i}let i=await Y(e,t,n);for(let e of i)if(e.fileName)return Z(e);return null},Q=e=>e.split(`/`).filter(Boolean).length,ke=e=>e.split(`/`).filter(Boolean)[0]??null,Ae=e=>{let t=e.indexOf(`/`,1);if(t===-1||Q(e.slice(0,t))!==1)return e;let n=e.slice(t);if(!c.test(n)||Q(n)<2)return e;let r=ke(n);return!r||r.startsWith(`@`)||r.length>4?e:n},$=e=>{if(!e||s.some(t=>t===e))return``;let t=e,n=t.startsWith(`http://`)||t.startsWith(`https://`);if(n)try{t=new URL(t).pathname}catch{}if(n&&(t=Ae(t)),t.startsWith(`about://React/`)){let e=t.slice(14),n=e.indexOf(`/`),r=e.indexOf(`:`);t=n!==-1&&(r===-1||n<r)?e.slice(n+1):e}let r=!0;for(;r;){r=!1;for(let e of a)if(t.startsWith(e)){t=t.slice(e.length),e===`file:///`&&(t=`/${t.replace(/^\/+/,``)}`),r=!0;break}}if(i.test(t)){let e=t.match(i);e&&(t=t.slice(e[0].length))}if(t.startsWith(`//`)){let e=t.indexOf(`/`,2);t=e===-1?``:t.slice(e)}let o=t.indexOf(`?`);if(o!==-1){let e=t.slice(o);u.test(e)&&(t=t.slice(0,o))}return t},je=e=>{let t=$(e);return!(!t||!c.test(t)||l.test(t))};export{X as a,N as c,m as d,q as i,I as l,je as n,Y as o,$ as r,R as s,Oe as t,L as u};

9
node_modules/bippy/dist/index.cjs generated vendored Normal file
View File

@@ -0,0 +1,9 @@
/**
* @license bippy
*
* Copyright (c) Aiden Bai
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./rdt-hook.cjs`);require(`./install-hook-only.cjs`);const t=require(`./core.cjs`);exports.ActivityComponentTag=t.ActivityComponentTag,exports.BIPPY_INSTRUMENTATION_STRING=e.t,exports.CONCURRENT_MODE_NUMBER=t.CONCURRENT_MODE_NUMBER,exports.CONCURRENT_MODE_SYMBOL_DESCRIPTION=t.CONCURRENT_MODE_SYMBOL_DESCRIPTION,exports.CONCURRENT_MODE_SYMBOL_STRING=t.CONCURRENT_MODE_SYMBOL_STRING,exports.ClassComponentTag=t.ClassComponentTag,exports.ContextConsumerTag=t.ContextConsumerTag,exports.DEPRECATED_ASYNC_MODE_SYMBOL_DESCRIPTION=t.DEPRECATED_ASYNC_MODE_SYMBOL_DESCRIPTION,exports.DEPRECATED_ASYNC_MODE_SYMBOL_STRING=t.DEPRECATED_ASYNC_MODE_SYMBOL_STRING,exports.DehydratedSuspenseComponentTag=t.DehydratedSuspenseComponentTag,exports.ELEMENT_TYPE_SYMBOL_STRING=t.ELEMENT_TYPE_SYMBOL_STRING,exports.ForwardRefTag=t.ForwardRefTag,exports.FragmentTag=t.FragmentTag,exports.FunctionComponentTag=t.FunctionComponentTag,exports.HostComponentTag=t.HostComponentTag,exports.HostHoistableTag=t.HostHoistableTag,exports.HostPortalTag=t.HostPortalTag,exports.HostRootTag=t.HostRootTag,exports.HostSingletonTag=t.HostSingletonTag,exports.HostTextTag=t.HostTextTag,exports.LazyComponentTag=t.LazyComponentTag,exports.LegacyHiddenComponentTag=t.LegacyHiddenComponentTag,exports.MemoComponentTag=t.MemoComponentTag,exports.OffscreenComponentTag=t.OffscreenComponentTag,exports.SimpleMemoComponentTag=t.SimpleMemoComponentTag,exports.SuspenseComponentTag=t.SuspenseComponentTag,exports.SuspenseListComponentTag=t.SuspenseListComponentTag,exports.TRANSITIONAL_ELEMENT_TYPE_SYMBOL_STRING=t.TRANSITIONAL_ELEMENT_TYPE_SYMBOL_STRING,exports.ViewTransitionComponentTag=t.ViewTransitionComponentTag,exports._fiberRoots=t._fiberRoots,exports._onActiveListeners=e.n,exports._renderers=e.r,exports.detectReactBuildType=t.detectReactBuildType,exports.didFiberCommit=t.didFiberCommit,exports.didFiberRender=t.didFiberRender,exports.getDisplayName=t.getDisplayName,exports.getFiberFromHostInstance=t.getFiberFromHostInstance,exports.getFiberId=t.getFiberId,exports.getFiberStack=t.getFiberStack,exports.getLatestFiber=t.getLatestFiber,exports.getMutatedHostFibers=t.getMutatedHostFibers,exports.getNearestHostFiber=t.getNearestHostFiber,exports.getNearestHostFibers=t.getNearestHostFibers,exports.getRDTHook=e.i,exports.getTimings=t.getTimings,exports.getType=t.getType,exports.hasMemoCache=t.hasMemoCache,exports.hasRDTHook=e.a,exports.installRDTHook=e.o,exports.instrument=t.instrument,exports.isClientEnvironment=e.s,exports.isCompositeFiber=t.isCompositeFiber,exports.isFiber=t.isFiber,exports.isHostFiber=t.isHostFiber,exports.isInstrumentationActive=t.isInstrumentationActive,exports.isReactRefresh=e.c,exports.isRealReactDevtools=e.l,exports.isValidElement=t.isValidElement,exports.isValidFiber=t.isValidFiber,exports.onRendererInject=e.u,exports.overrideContext=t.overrideContext,exports.overrideHookState=t.overrideHookState,exports.overrideProps=t.overrideProps,exports.patchRDTHook=e.d,exports.safelyInstallRDTHook=e.f,exports.setFiberId=t.setFiberId,exports.toUnsubscribe=e.m,exports.traverseContexts=t.traverseContexts,exports.traverseFiber=t.traverseFiber,exports.traverseProps=t.traverseProps,exports.traverseRenderedFibers=t.traverseRenderedFibers,exports.traverseState=t.traverseState,exports.version=e.p;

3
node_modules/bippy/dist/index.d.cts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import { A as ReactRenderer, B as TextSelector, C as React$AbstractComponent, D as ReactPortal, E as ReactDevToolsGlobalHook, F as Selector, H as TransitionTracingCallbacks, I as ServerComponentInfo, L as Source, M as RendererRefreshUpdate, N as RoleSelector, O as ReactProvider, P as RootTag, R as SuspenseHydrationCallbacks, S as Props, T as ReactContext, U as TypeOfMode, V as Thenable, W as WorkTag, _ as Lanes, a as ContextDependency, b as OpaqueHandle, c as Effect, d as FiberRoot, f as Flags, g as LanePriority, h as HostConfig, i as ComponentSelector, j as RefObject, k as ReactProviderType, l as Family, m as HookType, n as toUnsubscribe, o as Dependencies, p as HasPseudoClassSelector, r as BundleType, s as DevToolsConfig, t as Unsubscribe, u as Fiber, v as MemoizedState, w as ReactConsumer, x as OpaqueRoot, y as MutableSource, z as TestNameSelector } from "./unsubscribe.cjs";
import { $ as isValidFiber, A as TRANSITIONAL_ELEMENT_TYPE_SYMBOL_STRING, B as getLatestFiber, C as MemoComponentTag, D as SimpleMemoComponentTag, E as RenderPhase, F as didFiberRender, G as getType, H as getNearestHostFiber, I as getDisplayName, J as isCompositeFiber, K as hasMemoCache, L as getFiberFromHostInstance, M as _fiberRoots, N as detectReactBuildType, O as SuspenseComponentTag, P as didFiberCommit, Q as isValidElement, R as getFiberId, S as LegacyHiddenComponentTag, T as RenderHandler, U as getNearestHostFibers, V as getMutatedHostFibers, W as getTimings, X as isHostFiber, Y as isFiber, Z as isInstrumentationActive, _ as HostRootTag, _t as isRealReactDevtools, a as ClassComponentTag, at as traverseFiber, b as InstrumentationOptions, bt as safelyInstallRDTHook, c as DEPRECATED_ASYNC_MODE_SYMBOL_STRING, ct as traverseState, d as ForwardRefTag, dt as _renderers, et as overrideContext, f as FragmentTag, ft as getRDTHook, g as HostPortalTag, gt as isReactRefresh, h as HostHoistableTag, ht as isClientEnvironment, i as CONCURRENT_MODE_SYMBOL_STRING, it as traverseContexts, j as ViewTransitionComponentTag, k as SuspenseListComponentTag, l as DehydratedSuspenseComponentTag, lt as BIPPY_INSTRUMENTATION_STRING, m as HostComponentTag, mt as installRDTHook, n as CONCURRENT_MODE_NUMBER, nt as overrideProps, o as ContextConsumerTag, ot as traverseProps, p as FunctionComponentTag, pt as hasRDTHook, q as instrument, r as CONCURRENT_MODE_SYMBOL_DESCRIPTION, rt as setFiberId, s as DEPRECATED_ASYNC_MODE_SYMBOL_DESCRIPTION, st as traverseRenderedFibers, t as ActivityComponentTag, tt as overrideHookState, u as ELEMENT_TYPE_SYMBOL_STRING, ut as _onActiveListeners, v as HostSingletonTag, vt as onRendererInject, w as OffscreenComponentTag, x as LazyComponentTag, xt as version, y as HostTextTag, yt as patchRDTHook, z as getFiberStack } from "./core.cjs";
export { ActivityComponentTag, BIPPY_INSTRUMENTATION_STRING, BundleType, CONCURRENT_MODE_NUMBER, CONCURRENT_MODE_SYMBOL_DESCRIPTION, CONCURRENT_MODE_SYMBOL_STRING, ClassComponentTag, ComponentSelector, ContextConsumerTag, ContextDependency, DEPRECATED_ASYNC_MODE_SYMBOL_DESCRIPTION, DEPRECATED_ASYNC_MODE_SYMBOL_STRING, DehydratedSuspenseComponentTag, Dependencies, DevToolsConfig, ELEMENT_TYPE_SYMBOL_STRING, Effect, Family, Fiber, FiberRoot, Flags, ForwardRefTag, FragmentTag, FunctionComponentTag, HasPseudoClassSelector, HookType, HostComponentTag, HostConfig, HostHoistableTag, HostPortalTag, HostRootTag, HostSingletonTag, HostTextTag, InstrumentationOptions, LanePriority, Lanes, LazyComponentTag, LegacyHiddenComponentTag, MemoComponentTag, MemoizedState, MutableSource, OffscreenComponentTag, OpaqueHandle, OpaqueRoot, Props, React$AbstractComponent, ReactConsumer, ReactContext, ReactDevToolsGlobalHook, ReactPortal, ReactProvider, ReactProviderType, ReactRenderer, RefObject, RenderHandler, RenderPhase, RendererRefreshUpdate, RoleSelector, RootTag, Selector, ServerComponentInfo, SimpleMemoComponentTag, Source, SuspenseComponentTag, SuspenseHydrationCallbacks, SuspenseListComponentTag, TRANSITIONAL_ELEMENT_TYPE_SYMBOL_STRING, TestNameSelector, TextSelector, Thenable, TransitionTracingCallbacks, TypeOfMode, Unsubscribe, ViewTransitionComponentTag, WorkTag, _fiberRoots, _onActiveListeners, _renderers, detectReactBuildType, didFiberCommit, didFiberRender, getDisplayName, getFiberFromHostInstance, getFiberId, getFiberStack, getLatestFiber, getMutatedHostFibers, getNearestHostFiber, getNearestHostFibers, getRDTHook, getTimings, getType, hasMemoCache, hasRDTHook, installRDTHook, instrument, isClientEnvironment, isCompositeFiber, isFiber, isHostFiber, isInstrumentationActive, isReactRefresh, isRealReactDevtools, isValidElement, isValidFiber, onRendererInject, overrideContext, overrideHookState, overrideProps, patchRDTHook, safelyInstallRDTHook, setFiberId, toUnsubscribe, traverseContexts, traverseFiber, traverseProps, traverseRenderedFibers, traverseState, version };

3
node_modules/bippy/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import { A as ReactRenderer, B as TextSelector, C as React$AbstractComponent, D as ReactPortal, E as ReactDevToolsGlobalHook, F as Selector, H as TransitionTracingCallbacks, I as ServerComponentInfo, L as Source, M as RendererRefreshUpdate, N as RoleSelector, O as ReactProvider, P as RootTag, R as SuspenseHydrationCallbacks, S as Props, T as ReactContext, U as TypeOfMode, V as Thenable, W as WorkTag, _ as Lanes, a as ContextDependency, b as OpaqueHandle, c as Effect, d as FiberRoot, f as Flags, g as LanePriority, h as HostConfig, i as ComponentSelector, j as RefObject, k as ReactProviderType, l as Family, m as HookType, n as toUnsubscribe, o as Dependencies, p as HasPseudoClassSelector, r as BundleType, s as DevToolsConfig, t as Unsubscribe, u as Fiber, v as MemoizedState, w as ReactConsumer, x as OpaqueRoot, y as MutableSource, z as TestNameSelector } from "./unsubscribe.js";
import { $ as isValidFiber, A as TRANSITIONAL_ELEMENT_TYPE_SYMBOL_STRING, B as getLatestFiber, C as MemoComponentTag, D as SimpleMemoComponentTag, E as RenderPhase, F as didFiberRender, G as getType, H as getNearestHostFiber, I as getDisplayName, J as isCompositeFiber, K as hasMemoCache, L as getFiberFromHostInstance, M as _fiberRoots, N as detectReactBuildType, O as SuspenseComponentTag, P as didFiberCommit, Q as isValidElement, R as getFiberId, S as LegacyHiddenComponentTag, T as RenderHandler, U as getNearestHostFibers, V as getMutatedHostFibers, W as getTimings, X as isHostFiber, Y as isFiber, Z as isInstrumentationActive, _ as HostRootTag, _t as isRealReactDevtools, a as ClassComponentTag, at as traverseFiber, b as InstrumentationOptions, bt as safelyInstallRDTHook, c as DEPRECATED_ASYNC_MODE_SYMBOL_STRING, ct as traverseState, d as ForwardRefTag, dt as _renderers, et as overrideContext, f as FragmentTag, ft as getRDTHook, g as HostPortalTag, gt as isReactRefresh, h as HostHoistableTag, ht as isClientEnvironment, i as CONCURRENT_MODE_SYMBOL_STRING, it as traverseContexts, j as ViewTransitionComponentTag, k as SuspenseListComponentTag, l as DehydratedSuspenseComponentTag, lt as BIPPY_INSTRUMENTATION_STRING, m as HostComponentTag, mt as installRDTHook, n as CONCURRENT_MODE_NUMBER, nt as overrideProps, o as ContextConsumerTag, ot as traverseProps, p as FunctionComponentTag, pt as hasRDTHook, q as instrument, r as CONCURRENT_MODE_SYMBOL_DESCRIPTION, rt as setFiberId, s as DEPRECATED_ASYNC_MODE_SYMBOL_DESCRIPTION, st as traverseRenderedFibers, t as ActivityComponentTag, tt as overrideHookState, u as ELEMENT_TYPE_SYMBOL_STRING, ut as _onActiveListeners, v as HostSingletonTag, vt as onRendererInject, w as OffscreenComponentTag, x as LazyComponentTag, xt as version, y as HostTextTag, yt as patchRDTHook, z as getFiberStack } from "./core.js";
export { ActivityComponentTag, BIPPY_INSTRUMENTATION_STRING, BundleType, CONCURRENT_MODE_NUMBER, CONCURRENT_MODE_SYMBOL_DESCRIPTION, CONCURRENT_MODE_SYMBOL_STRING, ClassComponentTag, ComponentSelector, ContextConsumerTag, ContextDependency, DEPRECATED_ASYNC_MODE_SYMBOL_DESCRIPTION, DEPRECATED_ASYNC_MODE_SYMBOL_STRING, DehydratedSuspenseComponentTag, Dependencies, DevToolsConfig, ELEMENT_TYPE_SYMBOL_STRING, Effect, Family, Fiber, FiberRoot, Flags, ForwardRefTag, FragmentTag, FunctionComponentTag, HasPseudoClassSelector, HookType, HostComponentTag, HostConfig, HostHoistableTag, HostPortalTag, HostRootTag, HostSingletonTag, HostTextTag, InstrumentationOptions, LanePriority, Lanes, LazyComponentTag, LegacyHiddenComponentTag, MemoComponentTag, MemoizedState, MutableSource, OffscreenComponentTag, OpaqueHandle, OpaqueRoot, Props, React$AbstractComponent, ReactConsumer, ReactContext, ReactDevToolsGlobalHook, ReactPortal, ReactProvider, ReactProviderType, ReactRenderer, RefObject, RenderHandler, RenderPhase, RendererRefreshUpdate, RoleSelector, RootTag, Selector, ServerComponentInfo, SimpleMemoComponentTag, Source, SuspenseComponentTag, SuspenseHydrationCallbacks, SuspenseListComponentTag, TRANSITIONAL_ELEMENT_TYPE_SYMBOL_STRING, TestNameSelector, TextSelector, Thenable, TransitionTracingCallbacks, TypeOfMode, Unsubscribe, ViewTransitionComponentTag, WorkTag, _fiberRoots, _onActiveListeners, _renderers, detectReactBuildType, didFiberCommit, didFiberRender, getDisplayName, getFiberFromHostInstance, getFiberId, getFiberStack, getLatestFiber, getMutatedHostFibers, getNearestHostFiber, getNearestHostFibers, getRDTHook, getTimings, getType, hasMemoCache, hasRDTHook, installRDTHook, instrument, isClientEnvironment, isCompositeFiber, isFiber, isHostFiber, isInstrumentationActive, isReactRefresh, isRealReactDevtools, isValidElement, isValidFiber, onRendererInject, overrideContext, overrideHookState, overrideProps, patchRDTHook, safelyInstallRDTHook, setFiberId, toUnsubscribe, traverseContexts, traverseFiber, traverseProps, traverseRenderedFibers, traverseState, version };

9
node_modules/bippy/dist/index.iife.js generated vendored Normal file

File diff suppressed because one or more lines are too long

9
node_modules/bippy/dist/index.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
/**
* @license bippy
*
* Copyright (c) Aiden Bai
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import{a as e,c as t,d as n,f as r,i,l as a,m as o,n as s,o as c,p as l,r as u,s as d,t as f,u as p}from"./rdt-hook.js";import"./install-hook-only.js";import{ActivityComponentTag as m,CONCURRENT_MODE_NUMBER as h,CONCURRENT_MODE_SYMBOL_DESCRIPTION as g,CONCURRENT_MODE_SYMBOL_STRING as _,ClassComponentTag as v,ContextConsumerTag as y,DEPRECATED_ASYNC_MODE_SYMBOL_DESCRIPTION as b,DEPRECATED_ASYNC_MODE_SYMBOL_STRING as x,DehydratedSuspenseComponentTag as S,ELEMENT_TYPE_SYMBOL_STRING as C,ForwardRefTag as w,FragmentTag as T,FunctionComponentTag as E,HostComponentTag as D,HostHoistableTag as O,HostPortalTag as k,HostRootTag as A,HostSingletonTag as j,HostTextTag as M,LazyComponentTag as N,LegacyHiddenComponentTag as P,MemoComponentTag as F,OffscreenComponentTag as I,SimpleMemoComponentTag as L,SuspenseComponentTag as R,SuspenseListComponentTag as z,TRANSITIONAL_ELEMENT_TYPE_SYMBOL_STRING as B,ViewTransitionComponentTag as V,_fiberRoots as H,detectReactBuildType as U,didFiberCommit as W,didFiberRender as G,getDisplayName as K,getFiberFromHostInstance as q,getFiberId as J,getFiberStack as Y,getLatestFiber as X,getMutatedHostFibers as Z,getNearestHostFiber as Q,getNearestHostFibers as $,getTimings as ee,getType as te,hasMemoCache as ne,instrument as re,isCompositeFiber as ie,isFiber as ae,isHostFiber as oe,isInstrumentationActive as se,isValidElement as ce,isValidFiber as le,overrideContext as ue,overrideHookState as de,overrideProps as fe,setFiberId as pe,traverseContexts as me,traverseFiber as he,traverseProps as ge,traverseRenderedFibers as _e,traverseState as ve}from"./core.js";export{m as ActivityComponentTag,f as BIPPY_INSTRUMENTATION_STRING,h as CONCURRENT_MODE_NUMBER,g as CONCURRENT_MODE_SYMBOL_DESCRIPTION,_ as CONCURRENT_MODE_SYMBOL_STRING,v as ClassComponentTag,y as ContextConsumerTag,b as DEPRECATED_ASYNC_MODE_SYMBOL_DESCRIPTION,x as DEPRECATED_ASYNC_MODE_SYMBOL_STRING,S as DehydratedSuspenseComponentTag,C as ELEMENT_TYPE_SYMBOL_STRING,w as ForwardRefTag,T as FragmentTag,E as FunctionComponentTag,D as HostComponentTag,O as HostHoistableTag,k as HostPortalTag,A as HostRootTag,j as HostSingletonTag,M as HostTextTag,N as LazyComponentTag,P as LegacyHiddenComponentTag,F as MemoComponentTag,I as OffscreenComponentTag,L as SimpleMemoComponentTag,R as SuspenseComponentTag,z as SuspenseListComponentTag,B as TRANSITIONAL_ELEMENT_TYPE_SYMBOL_STRING,V as ViewTransitionComponentTag,H as _fiberRoots,s as _onActiveListeners,u as _renderers,U as detectReactBuildType,W as didFiberCommit,G as didFiberRender,K as getDisplayName,q as getFiberFromHostInstance,J as getFiberId,Y as getFiberStack,X as getLatestFiber,Z as getMutatedHostFibers,Q as getNearestHostFiber,$ as getNearestHostFibers,i as getRDTHook,ee as getTimings,te as getType,ne as hasMemoCache,e as hasRDTHook,c as installRDTHook,re as instrument,d as isClientEnvironment,ie as isCompositeFiber,ae as isFiber,oe as isHostFiber,se as isInstrumentationActive,t as isReactRefresh,a as isRealReactDevtools,ce as isValidElement,le as isValidFiber,p as onRendererInject,ue as overrideContext,de as overrideHookState,fe as overrideProps,n as patchRDTHook,r as safelyInstallRDTHook,pe as setFiberId,o as toUnsubscribe,me as traverseContexts,he as traverseFiber,ge as traverseProps,_e as traverseRenderedFibers,ve as traverseState,l as version};

9
node_modules/bippy/dist/install-hook-only.cjs generated vendored Normal file
View File

@@ -0,0 +1,9 @@
/**
* @license bippy
*
* Copyright (c) Aiden Bai
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
require(`./rdt-hook.cjs`).f();

1
node_modules/bippy/dist/install-hook-only.d.cts generated vendored Normal file
View File

@@ -0,0 +1 @@
export { };

1
node_modules/bippy/dist/install-hook-only.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export { };

9
node_modules/bippy/dist/install-hook-only.iife.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
/**
* @license bippy
*
* Copyright (c) Aiden Bai
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
(function(){let e=`bippy-0.6.1`,t=Object.defineProperty,n=Object.prototype.hasOwnProperty,r=()=>{},i=e=>{try{Function.prototype.toString.call(e).indexOf(`^_^`)>-1&&setTimeout(()=>{throw Error(`React is running in production mode, but dead code elimination has not been applied. Read how to correctly configure React for production: https://reactjs.org/link/perf-use-production-build`)})}catch{}},a=(e=globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__)=>!!(e&&`getFiberRoots`in e),o=!1,s,c=(e=globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__)=>o?!0:(e&&typeof e.inject==`function`&&(s=e.inject.toString()),!!s?.includes(`(injected)`)),l=new Set,u=new Set,d=n=>{n&&l.add(n);let a=new Map,o=0,s={_instrumentationIsActive:!1,_instrumentationSource:e,checkDCE:i,hasUnsupportedRendererAttached:!1,inject(e){let t=++o;return a.set(t,e),u.add(e),s._instrumentationIsActive||(s._instrumentationIsActive=!0,l.forEach(e=>e())),t},on:r,onCommitFiberRoot:r,onCommitFiberUnmount:r,onPostCommitFiberRoot:r,renderers:a,supportsFiber:!0,supportsFlight:!0};try{t(globalThis,`__REACT_DEVTOOLS_GLOBAL_HOOK__`,{configurable:!0,enumerable:!0,get(){return s},set(e){if(e&&typeof e==`object`){let t=s.renderers;s=e,t.size>0&&(t.forEach((t,n)=>{u.add(t),e.renderers.set(n,t)}),f(n))}}});let e=window.hasOwnProperty,r=!1;t(window,`hasOwnProperty`,{configurable:!0,value:function(...t){try{if(!r&&t[0]===`__REACT_DEVTOOLS_GLOBAL_HOOK__`)return globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__=void 0,r=!0,-0}catch{}return e.apply(this,t)},writable:!0})}catch{f(n)}return s},f=t=>{t&&l.add(t);try{let n=globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!n)return;if(!n._instrumentationSource){n.checkDCE=i,n.supportsFiber=!0,n.supportsFlight=!0,n.hasUnsupportedRendererAttached=!1,n._instrumentationSource=e,n._instrumentationIsActive=!1;let t=a(n);if(t||(n.on=r),n.renderers.size){n._instrumentationIsActive=!0,l.forEach(e=>e());return}let s=n.inject,d=c(n);d&&!t&&(o=!0,n.inject({scheduleRefresh(){}})&&(n._instrumentationIsActive=!0)),n.inject=e=>{let t=s(e);return u.add(e),d&&n.renderers.set(t,e),n._instrumentationIsActive=!0,l.forEach(e=>e()),t}}(n.renderers.size||n._instrumentationIsActive||c())&&t?.()}catch{}},p=()=>n.call(globalThis,`__REACT_DEVTOOLS_GLOBAL_HOOK__`),m=e=>p()?(f(e),globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__):d(e),h=()=>!!(typeof window<`u`&&(window.document?.createElement||window.navigator?.product===`ReactNative`));(()=>{try{h()&&m()}catch{}})()})();

9
node_modules/bippy/dist/install-hook-only.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
/**
* @license bippy
*
* Copyright (c) Aiden Bai
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import{f as e}from"./rdt-hook.js";e();

9
node_modules/bippy/dist/rdt-hook.cjs generated vendored Normal file
View File

@@ -0,0 +1,9 @@
/**
* @license bippy
*
* Copyright (c) Aiden Bai
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const e=e=>Object.assign(e,{[Symbol.dispose]:e}),t=`0.6.1`,n=`bippy-${t}`,r=Object.defineProperty,i=Object.prototype.hasOwnProperty,a=()=>{},o=e=>{try{Function.prototype.toString.call(e).indexOf(`^_^`)>-1&&setTimeout(()=>{throw Error(`React is running in production mode, but dead code elimination has not been applied. Read how to correctly configure React for production: https://reactjs.org/link/perf-use-production-build`)})}catch{}},s=(e=globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__)=>!!(e&&`getFiberRoots`in e);let c=!1,l;const u=(e=globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__)=>c?!0:(e&&typeof e.inject==`function`&&(l=e.inject.toString()),!!l?.includes(`(injected)`)),d=new Set,f=new Set,p=new Set,m=new WeakSet;let h=null;const g=e=>{if(e.inject===h)return;let t=e.inject,n=n=>{let r=t.call(e,n);if(!m.has(n)){m.add(n);for(let e of p)e(n)}return r};e.inject=n,h=n},_=t=>(g(x()),p.add(t),e(()=>{p.delete(t)})),v=e=>{e&&d.add(e);let t=new Map,i=0,s={_instrumentationIsActive:!1,_instrumentationSource:n,checkDCE:o,hasUnsupportedRendererAttached:!1,inject(e){let n=++i;return t.set(n,e),f.add(e),s._instrumentationIsActive||(s._instrumentationIsActive=!0,d.forEach(e=>e())),n},on:a,onCommitFiberRoot:a,onCommitFiberUnmount:a,onPostCommitFiberRoot:a,renderers:t,supportsFiber:!0,supportsFlight:!0};try{r(globalThis,`__REACT_DEVTOOLS_GLOBAL_HOOK__`,{configurable:!0,enumerable:!0,get(){return s},set(t){if(t&&typeof t==`object`){let n=s.renderers;s=t,n.size>0&&(n.forEach((e,n)=>{f.add(e),t.renderers.set(n,e)}),y(e))}}});let t=window.hasOwnProperty,n=!1;r(window,`hasOwnProperty`,{configurable:!0,value:function(...e){try{if(!n&&e[0]===`__REACT_DEVTOOLS_GLOBAL_HOOK__`)return globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__=void 0,n=!0,-0}catch{}return t.apply(this,e)},writable:!0})}catch{y(e)}return s},y=e=>{e&&d.add(e);try{let t=globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!t)return;if(!t._instrumentationSource){t.checkDCE=o,t.supportsFiber=!0,t.supportsFlight=!0,t.hasUnsupportedRendererAttached=!1,t._instrumentationSource=n,t._instrumentationIsActive=!1;let e=s(t);if(e||(t.on=a),t.renderers.size){t._instrumentationIsActive=!0,d.forEach(e=>e());return}let r=t.inject,i=u(t);i&&!e&&(c=!0,t.inject({scheduleRefresh(){}})&&(t._instrumentationIsActive=!0)),t.inject=e=>{let n=r(e);return f.add(e),i&&t.renderers.set(n,e),t._instrumentationIsActive=!0,d.forEach(e=>e()),n}}(t.renderers.size||t._instrumentationIsActive||u())&&e?.()}catch{}},b=()=>i.call(globalThis,`__REACT_DEVTOOLS_GLOBAL_HOOK__`),x=e=>b()?(y(e),globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__):v(e),S=()=>!!(typeof window<`u`&&(window.document?.createElement||window.navigator?.product===`ReactNative`)),C=()=>{try{S()&&x()}catch{}};Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return y}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return C}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return e}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return _}});

9
node_modules/bippy/dist/rdt-hook.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
/**
* @license bippy
*
* Copyright (c) Aiden Bai
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const e=e=>Object.assign(e,{[Symbol.dispose]:e}),t=`0.6.1`,n=`bippy-${t}`,r=Object.defineProperty,i=Object.prototype.hasOwnProperty,a=()=>{},o=e=>{try{Function.prototype.toString.call(e).indexOf(`^_^`)>-1&&setTimeout(()=>{throw Error(`React is running in production mode, but dead code elimination has not been applied. Read how to correctly configure React for production: https://reactjs.org/link/perf-use-production-build`)})}catch{}},s=(e=globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__)=>!!(e&&`getFiberRoots`in e);let c=!1,l;const u=(e=globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__)=>c?!0:(e&&typeof e.inject==`function`&&(l=e.inject.toString()),!!l?.includes(`(injected)`)),d=new Set,f=new Set,p=new Set,m=new WeakSet;let h=null;const g=e=>{if(e.inject===h)return;let t=e.inject,n=n=>{let r=t.call(e,n);if(!m.has(n)){m.add(n);for(let e of p)e(n)}return r};e.inject=n,h=n},_=t=>(g(x()),p.add(t),e(()=>{p.delete(t)})),v=e=>{e&&d.add(e);let t=new Map,i=0,s={_instrumentationIsActive:!1,_instrumentationSource:n,checkDCE:o,hasUnsupportedRendererAttached:!1,inject(e){let n=++i;return t.set(n,e),f.add(e),s._instrumentationIsActive||(s._instrumentationIsActive=!0,d.forEach(e=>e())),n},on:a,onCommitFiberRoot:a,onCommitFiberUnmount:a,onPostCommitFiberRoot:a,renderers:t,supportsFiber:!0,supportsFlight:!0};try{r(globalThis,`__REACT_DEVTOOLS_GLOBAL_HOOK__`,{configurable:!0,enumerable:!0,get(){return s},set(t){if(t&&typeof t==`object`){let n=s.renderers;s=t,n.size>0&&(n.forEach((e,n)=>{f.add(e),t.renderers.set(n,e)}),y(e))}}});let t=window.hasOwnProperty,n=!1;r(window,`hasOwnProperty`,{configurable:!0,value:function(...e){try{if(!n&&e[0]===`__REACT_DEVTOOLS_GLOBAL_HOOK__`)return globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__=void 0,n=!0,-0}catch{}return t.apply(this,e)},writable:!0})}catch{y(e)}return s},y=e=>{e&&d.add(e);try{let t=globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!t)return;if(!t._instrumentationSource){t.checkDCE=o,t.supportsFiber=!0,t.supportsFlight=!0,t.hasUnsupportedRendererAttached=!1,t._instrumentationSource=n,t._instrumentationIsActive=!1;let e=s(t);if(e||(t.on=a),t.renderers.size){t._instrumentationIsActive=!0,d.forEach(e=>e());return}let r=t.inject,i=u(t);i&&!e&&(c=!0,t.inject({scheduleRefresh(){}})&&(t._instrumentationIsActive=!0)),t.inject=e=>{let n=r(e);return f.add(e),i&&t.renderers.set(n,e),t._instrumentationIsActive=!0,d.forEach(e=>e()),n}}(t.renderers.size||t._instrumentationIsActive||u())&&e?.()}catch{}},b=()=>i.call(globalThis,`__REACT_DEVTOOLS_GLOBAL_HOOK__`),x=e=>b()?(y(e),globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__):v(e),S=()=>!!(typeof window<`u`&&(window.document?.createElement||window.navigator?.product===`ReactNative`)),C=()=>{try{S()&&x()}catch{}};export{b as a,u as c,y as d,C as f,x as i,s as l,e as m,d as n,v as o,t as p,f as r,S as s,n as t,_ as u};

9
node_modules/bippy/dist/react-refresh.cjs generated vendored Normal file
View File

@@ -0,0 +1,9 @@
/**
* @license bippy
*
* Copyright (c) Aiden Bai
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./rdt-hook.cjs`),t=require(`./core.cjs`),n=require(`./get-source.cjs`),r=1e3,i=/wsToken = "([^"]+)"/,a=/\.(?:tsx|ts|jsx|js|mjs|cjs|css)$/,o=/^(?:\.\/)?\/?\([a-z][a-z0-9-]*\)\//,s=e=>{if(typeof e!=`object`||!e||!(`getConstants`in e))return null;let t=e.getConstants;if(typeof t!=`function`)return null;let n;try{n=t.call(e)}catch{return null}if(typeof n!=`object`||!n||!(`scriptURL`in n))return null;let r=n.scriptURL;return typeof r==`string`?r:null},c=()=>{if(typeof globalThis.__turboModuleProxy==`function`){let e;try{e=globalThis.__turboModuleProxy(`SourceCode`)}catch{e=null}let t=s(e);if(t)return t}let e=globalThis.nativeModuleProxy?.SourceCode;return s(e)},l=e=>e.replace(`//&`,`?`),u=e=>{let t;try{t=new URL(l(e))}catch{return null}let n=decodeURIComponent(t.pathname);return n.startsWith(`/`)&&(n=n.slice(1)),n.endsWith(`.bundle`)&&(n=n.slice(0,-7)),n.length>0?n:null},d=(e,t)=>{if(Array.isArray(e))for(let n of e){if(typeof n!=`object`||!n||!(`sourceURL`in n)||typeof n.sourceURL!=`string`)continue;let e=u(n.sourceURL);!e||e.includes(`node_modules`)||t.push(e)}},f=e=>{let t;try{t=JSON.parse(e)}catch{return[]}if(typeof t!=`object`||!t||!(`type`in t)||t.type!==`update`||!(`body`in t)||typeof t.body!=`object`||t.body===null)return[];let n=t.body;if(`isInitialUpdate`in n&&n.isInitialUpdate===!0)return[];let r=[];return`added`in n&&d(n.added,r),`modified`in n&&d(n.modified,r),r},p=(e,t={})=>{if(typeof WebSocket>`u`)return null;let n=t.bundleUrl??c();if(!n)return null;let i;try{let e=new URL(n);i=`${e.protocol===`https:`?`wss`:`ws`}://${e.host}/hot`}catch{return null}let a=!1,o=null,s,l=()=>{a||(s=setTimeout(u,r))},u=()=>{if(a)return;let t=new WebSocket(i);o=t,t.onopen=()=>{t.send(JSON.stringify({type:`register-entrypoints`,entryPoints:[n]}))},t.onmessage=t=>{let n=f(String(t.data));n.length>0&&e(n)},t.onclose=l};return u(),{dispose:()=>{a=!0,clearTimeout(s),o&&(o.onclose=null,o.close())}}},m=e=>{let t=n.r(e);return t=t.replace(o,``),t.startsWith(`./`)&&(t=t.slice(2)),t},h=e=>{let t=[];for(let n of e){if(n.includes(`node_modules`))continue;let e=m(n);a.test(e)&&t.push(e)}return t},g=e=>{if(typeof window>`u`)return null;let t=window.webpackHotUpdate_N_E;if(typeof t!=`function`)return null;let n=(n,r,i)=>{let a=h(Object.keys(r??{}));a.length>0&&e(a),t(n,r,i)};return window.webpackHotUpdate_N_E=n,{dispose:()=>{window.webpackHotUpdate_N_E===n&&(window.webpackHotUpdate_N_E=t)}}},_=e=>{let t;try{t=JSON.parse(e)}catch{return[]}if(typeof t!=`object`||!t||!(`type`in t)||t.type!==`update`||!(`updates`in t)||!Array.isArray(t.updates))return[];let n=[];for(let e of t.updates)typeof e!=`object`||!e||!(`type`in e)||e.type!==`js-update`||!(`acceptedPath`in e)||typeof e.acceptedPath!=`string`||n.push(e.acceptedPath);return n},v=async()=>{try{let e=await fetch(`/@vite/client`);if(!e.ok)return null;let t=await e.text();return i.exec(t)?.[1]??null}catch{return null}},y=async e=>{if(typeof window>`u`||typeof WebSocket>`u`)return null;let t=await v();if(!t)return null;let n=!1,i=null,a,o=()=>{n||(a=window.setTimeout(()=>{v().then(e=>{n||(e?s(e):o())})},r))},s=t=>{if(n)return;let r=location.protocol===`https:`?`wss`:`ws`,a=new WebSocket(`${r}://${location.host}/?token=${t}`,`vite-hmr`);i=a,a.onmessage=t=>{let n=_(String(t.data));n.length>0&&e(n)},a.onclose=o};return s(t),{dispose:()=>{n=!0,window.clearTimeout(a),i&&(i.onclose=null,i.close())}}},b=async t=>e.s()?g(t)||p(t)||y(t):null,x=(e,n)=>{if(n.size===0||!e.current)return[];let r=[];return t.traverseFiber(e.current,e=>{(n.has(e.type)||n.has(t.getType(e.type)))&&r.push(e)}),r},S=new Set,C=new WeakSet;let w=[],T=0;const E=e=>{let t=Date.now();t-T>1e4&&(w=[]),w.push(...e),T=t},D=()=>{if(Date.now()-T>1e4)return[];let e=[...w];return queueMicrotask(()=>{w=[]}),e},O=e=>{if(C.has(e))return;let t=e.scheduleRefresh;typeof t==`function`&&(C.add(e),e.scheduleRefresh=(n,r)=>{if(t.call(e,n,r),S.size===0)return;let i=Array.from(r.staleFamilies,e=>e.current),a=Array.from(r.updatedFamilies,e=>e.current),o={filePaths:D(),root:n,staleComponents:i,staleFibers:x(n,new Set(i)),updatedComponents:a,updatedFibers:x(n,new Set(a))};for(let e of S)e(o)})};let k=!1;const A=()=>{if(k)return;k=!0;let t=e.i();for(let e of t.renderers.values())O(e);e.u(O)};let j=null;const M=()=>{b(E).then(e=>{e&&(j?.dispose(),j=e)})},N=t=>{let{onRefresh:n}=t;return!n||!e.s()?e.m(()=>{}):(A(),S.size===0&&M(),S.add(n),e.m(()=>{S.delete(n)}))};exports.instrumentReactRefresh=N;

66
node_modules/bippy/dist/react-refresh.d.cts generated vendored Normal file
View File

@@ -0,0 +1,66 @@
import { d as FiberRoot, t as Unsubscribe, u as Fiber } from "./unsubscribe.cjs";
//#region src/react-refresh/index.d.ts
interface ReactRefreshUpdate {
/**
* hot-updated source file paths reported by the bundler's HMR transport
* (auto-detected: Next.js webpack, Metro, Vite). Best-effort: empty when
* the bundler does not expose a transport (e.g. Turbopack) or when the
* transport message has not arrived yet (e.g. Metro delivers updates on
* an independent socket).
*/
filePaths: string[];
root: FiberRoot;
/** new component types that were remounted, losing state */
staleComponents: unknown[];
/** mounted fibers whose component types were remounted */
staleFibers: Fiber[];
/** new component types that re-rendered preserving state */
updatedComponents: unknown[];
/** mounted fibers whose component types re-rendered preserving state */
updatedFibers: Fiber[];
}
interface ReactRefreshHandler {
(update: ReactRefreshUpdate): void;
}
interface ReactRefreshInstrumentationOptions {
onRefresh?: ReactRefreshHandler;
}
/**
* Subscribes to react-refresh (fast refresh) updates by wrapping
* `scheduleRefresh` on every renderer injected into the React DevTools
* global hook. The react-refresh runtime calls `scheduleRefresh` after each
* hot update, so this works with any bundler that uses react-refresh (Vite,
* Next.js webpack, Next.js Turbopack, Metro) without bundler-specific code.
* Returns an unsubscribe function (a no-op in non-client environments like
* SSR, so callers never need an environment check). The returned function
* is also a `Disposable`, so it composes with other bippy subscriptions
* through `using`.
*
* The bundler's HMR transport is auto-detected and each refresh update is
* augmented with the hot-updated source file paths it reported.
*
* The handler runs after React has re-rendered with the new component
* types, so the refreshed root's fiber tree already carries them;
* `updatedFibers`/`staleFibers` are the mounted fibers matching the
* hot-swapped component types.
*
* @example
* ```ts
* const unsubscribe = instrumentReactRefresh({
* onRefresh(update) {
* for (const fiber of update.updatedFibers) {
* console.log("hot updated:", getDisplayName(fiber.type));
* }
* console.log("changed files:", update.filePaths);
* },
* });
* unsubscribe();
* ```
*
* Pair with `getSource(fiber)` from `bippy/source` to symbolicate the
* source locations of `updatedFibers` when needed.
*/
declare const instrumentReactRefresh: (options: ReactRefreshInstrumentationOptions) => Unsubscribe;
//#endregion
export { ReactRefreshHandler, ReactRefreshInstrumentationOptions, ReactRefreshUpdate, instrumentReactRefresh };

66
node_modules/bippy/dist/react-refresh.d.ts generated vendored Normal file
View File

@@ -0,0 +1,66 @@
import { d as FiberRoot, t as Unsubscribe, u as Fiber } from "./unsubscribe.js";
//#region src/react-refresh/index.d.ts
interface ReactRefreshUpdate {
/**
* hot-updated source file paths reported by the bundler's HMR transport
* (auto-detected: Next.js webpack, Metro, Vite). Best-effort: empty when
* the bundler does not expose a transport (e.g. Turbopack) or when the
* transport message has not arrived yet (e.g. Metro delivers updates on
* an independent socket).
*/
filePaths: string[];
root: FiberRoot;
/** new component types that were remounted, losing state */
staleComponents: unknown[];
/** mounted fibers whose component types were remounted */
staleFibers: Fiber[];
/** new component types that re-rendered preserving state */
updatedComponents: unknown[];
/** mounted fibers whose component types re-rendered preserving state */
updatedFibers: Fiber[];
}
interface ReactRefreshHandler {
(update: ReactRefreshUpdate): void;
}
interface ReactRefreshInstrumentationOptions {
onRefresh?: ReactRefreshHandler;
}
/**
* Subscribes to react-refresh (fast refresh) updates by wrapping
* `scheduleRefresh` on every renderer injected into the React DevTools
* global hook. The react-refresh runtime calls `scheduleRefresh` after each
* hot update, so this works with any bundler that uses react-refresh (Vite,
* Next.js webpack, Next.js Turbopack, Metro) without bundler-specific code.
* Returns an unsubscribe function (a no-op in non-client environments like
* SSR, so callers never need an environment check). The returned function
* is also a `Disposable`, so it composes with other bippy subscriptions
* through `using`.
*
* The bundler's HMR transport is auto-detected and each refresh update is
* augmented with the hot-updated source file paths it reported.
*
* The handler runs after React has re-rendered with the new component
* types, so the refreshed root's fiber tree already carries them;
* `updatedFibers`/`staleFibers` are the mounted fibers matching the
* hot-swapped component types.
*
* @example
* ```ts
* const unsubscribe = instrumentReactRefresh({
* onRefresh(update) {
* for (const fiber of update.updatedFibers) {
* console.log("hot updated:", getDisplayName(fiber.type));
* }
* console.log("changed files:", update.filePaths);
* },
* });
* unsubscribe();
* ```
*
* Pair with `getSource(fiber)` from `bippy/source` to symbolicate the
* source locations of `updatedFibers` when needed.
*/
declare const instrumentReactRefresh: (options: ReactRefreshInstrumentationOptions) => Unsubscribe;
//#endregion
export { ReactRefreshHandler, ReactRefreshInstrumentationOptions, ReactRefreshUpdate, instrumentReactRefresh };

9
node_modules/bippy/dist/react-refresh.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
/**
* @license bippy
*
* Copyright (c) Aiden Bai
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import{i as e,m as t,s as n,u as r}from"./rdt-hook.js";import{getType as i,traverseFiber as a}from"./core.js";import{r as o}from"./get-source.js";const s=1e3,c=/wsToken = "([^"]+)"/,l=/\.(?:tsx|ts|jsx|js|mjs|cjs|css)$/,u=/^(?:\.\/)?\/?\([a-z][a-z0-9-]*\)\//,d=e=>{if(typeof e!=`object`||!e||!(`getConstants`in e))return null;let t=e.getConstants;if(typeof t!=`function`)return null;let n;try{n=t.call(e)}catch{return null}if(typeof n!=`object`||!n||!(`scriptURL`in n))return null;let r=n.scriptURL;return typeof r==`string`?r:null},f=()=>{if(typeof globalThis.__turboModuleProxy==`function`){let e;try{e=globalThis.__turboModuleProxy(`SourceCode`)}catch{e=null}let t=d(e);if(t)return t}let e=globalThis.nativeModuleProxy?.SourceCode;return d(e)},p=e=>e.replace(`//&`,`?`),m=e=>{let t;try{t=new URL(p(e))}catch{return null}let n=decodeURIComponent(t.pathname);return n.startsWith(`/`)&&(n=n.slice(1)),n.endsWith(`.bundle`)&&(n=n.slice(0,-7)),n.length>0?n:null},h=(e,t)=>{if(Array.isArray(e))for(let n of e){if(typeof n!=`object`||!n||!(`sourceURL`in n)||typeof n.sourceURL!=`string`)continue;let e=m(n.sourceURL);!e||e.includes(`node_modules`)||t.push(e)}},g=e=>{let t;try{t=JSON.parse(e)}catch{return[]}if(typeof t!=`object`||!t||!(`type`in t)||t.type!==`update`||!(`body`in t)||typeof t.body!=`object`||t.body===null)return[];let n=t.body;if(`isInitialUpdate`in n&&n.isInitialUpdate===!0)return[];let r=[];return`added`in n&&h(n.added,r),`modified`in n&&h(n.modified,r),r},_=(e,t={})=>{if(typeof WebSocket>`u`)return null;let n=t.bundleUrl??f();if(!n)return null;let r;try{let e=new URL(n);r=`${e.protocol===`https:`?`wss`:`ws`}://${e.host}/hot`}catch{return null}let i=!1,a=null,o,c=()=>{i||(o=setTimeout(l,s))},l=()=>{if(i)return;let t=new WebSocket(r);a=t,t.onopen=()=>{t.send(JSON.stringify({type:`register-entrypoints`,entryPoints:[n]}))},t.onmessage=t=>{let n=g(String(t.data));n.length>0&&e(n)},t.onclose=c};return l(),{dispose:()=>{i=!0,clearTimeout(o),a&&(a.onclose=null,a.close())}}},v=e=>{let t=o(e);return t=t.replace(u,``),t.startsWith(`./`)&&(t=t.slice(2)),t},y=e=>{let t=[];for(let n of e){if(n.includes(`node_modules`))continue;let e=v(n);l.test(e)&&t.push(e)}return t},b=e=>{if(typeof window>`u`)return null;let t=window.webpackHotUpdate_N_E;if(typeof t!=`function`)return null;let n=(n,r,i)=>{let a=y(Object.keys(r??{}));a.length>0&&e(a),t(n,r,i)};return window.webpackHotUpdate_N_E=n,{dispose:()=>{window.webpackHotUpdate_N_E===n&&(window.webpackHotUpdate_N_E=t)}}},x=e=>{let t;try{t=JSON.parse(e)}catch{return[]}if(typeof t!=`object`||!t||!(`type`in t)||t.type!==`update`||!(`updates`in t)||!Array.isArray(t.updates))return[];let n=[];for(let e of t.updates)typeof e!=`object`||!e||!(`type`in e)||e.type!==`js-update`||!(`acceptedPath`in e)||typeof e.acceptedPath!=`string`||n.push(e.acceptedPath);return n},S=async()=>{try{let e=await fetch(`/@vite/client`);if(!e.ok)return null;let t=await e.text();return c.exec(t)?.[1]??null}catch{return null}},C=async e=>{if(typeof window>`u`||typeof WebSocket>`u`)return null;let t=await S();if(!t)return null;let n=!1,r=null,i,a=()=>{n||(i=window.setTimeout(()=>{S().then(e=>{n||(e?o(e):a())})},s))},o=t=>{if(n)return;let i=location.protocol===`https:`?`wss`:`ws`,o=new WebSocket(`${i}://${location.host}/?token=${t}`,`vite-hmr`);r=o,o.onmessage=t=>{let n=x(String(t.data));n.length>0&&e(n)},o.onclose=a};return o(t),{dispose:()=>{n=!0,window.clearTimeout(i),r&&(r.onclose=null,r.close())}}},w=async e=>n()?b(e)||_(e)||C(e):null,T=(e,t)=>{if(t.size===0||!e.current)return[];let n=[];return a(e.current,e=>{(t.has(e.type)||t.has(i(e.type)))&&n.push(e)}),n},E=new Set,D=new WeakSet;let O=[],k=0;const A=e=>{let t=Date.now();t-k>1e4&&(O=[]),O.push(...e),k=t},j=()=>{if(Date.now()-k>1e4)return[];let e=[...O];return queueMicrotask(()=>{O=[]}),e},M=e=>{if(D.has(e))return;let t=e.scheduleRefresh;typeof t==`function`&&(D.add(e),e.scheduleRefresh=(n,r)=>{if(t.call(e,n,r),E.size===0)return;let i=Array.from(r.staleFamilies,e=>e.current),a=Array.from(r.updatedFamilies,e=>e.current),o={filePaths:j(),root:n,staleComponents:i,staleFibers:T(n,new Set(i)),updatedComponents:a,updatedFibers:T(n,new Set(a))};for(let e of E)e(o)})};let N=!1;const P=()=>{if(N)return;N=!0;let t=e();for(let e of t.renderers.values())M(e);r(M)};let F=null;const I=()=>{w(A).then(e=>{e&&(F?.dispose(),F=e)})},L=e=>{let{onRefresh:r}=e;return!r||!n()?t(()=>{}):(P(),E.size===0&&I(),E.add(r),t(()=>{E.delete(r)}))};export{L as instrumentReactRefresh};

14
node_modules/bippy/dist/source.cjs generated vendored Normal file

File diff suppressed because one or more lines are too long

188
node_modules/bippy/dist/source.d.cts generated vendored Normal file
View File

@@ -0,0 +1,188 @@
import { u as Fiber } from "./unsubscribe.cjs";
//#region src/source/parse-stack.d.ts
interface StackFrame {
args?: unknown[];
columnNumber?: number;
lineNumber?: number;
enclosingLineNumber?: number;
enclosingColumnNumber?: number;
fileName?: string;
functionName?: string;
source?: string;
isServer?: boolean;
isSymbolicated?: boolean;
isIgnoreListed?: boolean;
}
interface ParseOptions {
slice?: number | [number, number];
allowEmpty?: boolean;
includeInElement?: boolean;
}
declare const parseStack: (stackString: string, options?: ParseOptions) => StackFrame[];
//#endregion
//#region src/source/owner-stack.d.ts
declare const hasDebugStack: (fiber: Fiber) => fiber is Fiber & {
_debugStack: NonNullable<Fiber["_debugStack"]>;
};
/**
* takes Error.stack and formats it to only the React owner stack
*
* before:
* ```
* Error: react-stack-top-frame
* at fakeJSXCallSite (http://localhost:3000/_next/static/chunks/<chunk-name>._.js:17665:16)
* at TodoItem (rsc://React/Server/file:///path/to/project/.next/server/chunks/ssr/<chunk-name>._.js)
* at react-stack-bottom-frame (http://localhost:3000/_next/static/chunks/<chunk-name>._.js:17984:89)
* ```
*
* after:
* ```
* at TodoItem (rsc://React/Server/file:///path/to/project/.next/server/chunks/ssr/<chunk-name>._.js)
* ```
*
* @see https://github.com/facebook/react/blob/main/packages/react-devtools-shared/src/backend/shared/DevToolsOwnerStack.js#L12
*/
declare const formatOwnerStack: (stack: string) => string;
/**
* Returns a stack of ALL ancestor components in the render tree (the fiber's
* `return` chain), including wrappers that render `{children}` without having
* created this fiber's JSX. Locations come from re-invoking each component
* with a throwing dispatcher; server frames are enriched from debug stacks by
* name matching. Works on every React version.
*/
declare const getParentStack: (fiber: Fiber, shouldCache?: boolean, fetchFunction?: (url: string) => Promise<Response>) => Promise<StackFrame[]>;
/**
* Returns the stack of components that CREATED this fiber's JSX (the
* `_debugOwner` chain), with exact creation-site locations from React 19's
* `_debugStack` errors - including server component owners. Wrappers that
* merely render `{children}` do not appear; use {@link getParentStack} for
* the full render-tree ancestry. Falls back to {@link getParentStack} on
* React <19, when no trusted debug stacks exist, or when the owner chain
* yields no locatable frames (so callers always get the most useful stack
* available).
*/
declare const getOwnerStack: (fiber: Fiber, shouldCache?: boolean, fetchFunction?: (url: string) => Promise<Response>) => Promise<StackFrame[]>;
//#endregion
//#region src/source/types.d.ts
interface FiberSource {
columnNumber?: number;
fileName: string;
lineNumber?: number;
functionName?: string;
}
//#endregion
//#region src/source/get-source.d.ts
/**
* Returns the source of where the component is used. Available only in dev, for composite {@link Fiber}s.
*
* Resolution order:
* 1. `_debugSource` (react <19, requires the JSX source babel transform)
* 2. the fiber's own `_debugStack` (react 19) - the exact JSX creation site
* 3. an owned child's `_debugStack` bottom frame (react 19) - a location
* inside the component's own body; works for components that the throwing
* trick cannot locate (no hooks, no props access)
* 4. the legacy owner-stack path (throwing trick re-invocation)
*
* @example
* ```ts
* function Parent() {
* const data = useData();
* return <Child name={data.name} />; // <-- captures THIS line
* }
*
* function Child({ name }) {
* return <div>{name}</div>;
* }
*
* const source = await getSource(fiber);
* console.log(source.fileName, source.lineNumber);
* ```
*/
declare const getSource: (fiber: Fiber, cache?: boolean, fetchFn?: (url: string) => Promise<Response>) => Promise<FiberSource | null>;
declare const normalizeFileName: (fileName: string) => string;
declare const isSourceFile: (fileName: string) => boolean;
//#endregion
//#region ../../node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts
type SourceMapSegment = [number] | [number, number, number, number] | [number, number, number, number, number];
//#endregion
//#region src/source/symbolication.d.ts
interface DecodedSourceMapSection {
map: {
file?: string;
ignoredSourceIndices?: Set<number>;
mappings: SourceMapSegment[][];
names?: string[];
sourceRoot?: string;
sources: string[];
sourcesContent?: string[];
version: 3;
};
offset: {
column: number;
line: number;
};
}
interface IndexSourceMap {
file?: string;
sections: Array<{
map: StandardSourceMap;
offset: {
column: number;
line: number;
};
}>;
version: 3;
}
type RawSourceMap = IndexSourceMap | StandardSourceMap;
interface SourceMap {
file?: string;
ignoredSourceIndices?: Set<number>;
mappings: SourceMapSegment[][];
names?: string[];
sections?: DecodedSourceMapSection[];
sourceRoot?: string;
sources: string[];
sourcesContent?: string[];
version: 3;
}
interface StandardSourceMap {
file?: string;
ignoreList?: number[];
mappings: string;
names?: string[];
sourceRoot?: string;
sources: string[];
sourcesContent?: string[];
version: 3;
x_google_ignoreList?: number[];
}
declare const getSourceFromSourceMap: (sourceMap: SourceMap, line: number, column: number) => StackFrame | null;
declare const getSourceMap: (file: string, useCache?: boolean, fetchFn?: (url: string) => Promise<Response>) => Promise<null | SourceMap>;
declare const symbolicateStack: (stack: StackFrame[], cache?: boolean, fetchFn?: (url: string) => Promise<Response>) => Promise<StackFrame[]>;
//#endregion
//#region src/source/get-display-name-from-source.d.ts
declare const getDisplayNameFromSource: (fiber: Fiber, cache?: boolean, fetchFn?: (url: string) => Promise<Response>) => Promise<string | null>;
//#endregion
//#region src/source/inspect-hooks.d.ts
interface HookSource {
lineNumber: number | null;
columnNumber: number | null;
fileName: string | null;
functionName: string | null;
}
interface HooksNode {
id: number | null;
isStateEditable: boolean;
name: string;
value: unknown;
subHooks: HooksNode[];
hookSource: HookSource | null;
}
interface HooksTree extends Array<HooksNode> {}
declare const getFiberHooks: (fiber: Fiber) => HooksTree;
//#endregion
//#region src/source/parse-hook-names.d.ts
interface HookNames extends Map<string, string> {}
declare const parseHookNames: (hooksTree: HooksTree, fetchFn?: (url: string) => Promise<Response>) => Promise<HookNames>;
//#endregion
export { type DecodedSourceMapSection, type FiberSource, type HookNames, type HookSource, type HooksNode, type HooksTree, type IndexSourceMap, type ParseOptions, type RawSourceMap, type SourceMap, type StackFrame, type StandardSourceMap, formatOwnerStack, getDisplayNameFromSource, getFiberHooks, getOwnerStack, getParentStack, getSource, getSourceFromSourceMap, getSourceMap, hasDebugStack, isSourceFile, normalizeFileName, parseHookNames, parseStack, symbolicateStack };

188
node_modules/bippy/dist/source.d.ts generated vendored Normal file
View File

@@ -0,0 +1,188 @@
import { u as Fiber } from "./unsubscribe.js";
//#region src/source/parse-stack.d.ts
interface StackFrame {
args?: unknown[];
columnNumber?: number;
lineNumber?: number;
enclosingLineNumber?: number;
enclosingColumnNumber?: number;
fileName?: string;
functionName?: string;
source?: string;
isServer?: boolean;
isSymbolicated?: boolean;
isIgnoreListed?: boolean;
}
interface ParseOptions {
slice?: number | [number, number];
allowEmpty?: boolean;
includeInElement?: boolean;
}
declare const parseStack: (stackString: string, options?: ParseOptions) => StackFrame[];
//#endregion
//#region src/source/owner-stack.d.ts
declare const hasDebugStack: (fiber: Fiber) => fiber is Fiber & {
_debugStack: NonNullable<Fiber["_debugStack"]>;
};
/**
* takes Error.stack and formats it to only the React owner stack
*
* before:
* ```
* Error: react-stack-top-frame
* at fakeJSXCallSite (http://localhost:3000/_next/static/chunks/<chunk-name>._.js:17665:16)
* at TodoItem (rsc://React/Server/file:///path/to/project/.next/server/chunks/ssr/<chunk-name>._.js)
* at react-stack-bottom-frame (http://localhost:3000/_next/static/chunks/<chunk-name>._.js:17984:89)
* ```
*
* after:
* ```
* at TodoItem (rsc://React/Server/file:///path/to/project/.next/server/chunks/ssr/<chunk-name>._.js)
* ```
*
* @see https://github.com/facebook/react/blob/main/packages/react-devtools-shared/src/backend/shared/DevToolsOwnerStack.js#L12
*/
declare const formatOwnerStack: (stack: string) => string;
/**
* Returns a stack of ALL ancestor components in the render tree (the fiber's
* `return` chain), including wrappers that render `{children}` without having
* created this fiber's JSX. Locations come from re-invoking each component
* with a throwing dispatcher; server frames are enriched from debug stacks by
* name matching. Works on every React version.
*/
declare const getParentStack: (fiber: Fiber, shouldCache?: boolean, fetchFunction?: (url: string) => Promise<Response>) => Promise<StackFrame[]>;
/**
* Returns the stack of components that CREATED this fiber's JSX (the
* `_debugOwner` chain), with exact creation-site locations from React 19's
* `_debugStack` errors - including server component owners. Wrappers that
* merely render `{children}` do not appear; use {@link getParentStack} for
* the full render-tree ancestry. Falls back to {@link getParentStack} on
* React <19, when no trusted debug stacks exist, or when the owner chain
* yields no locatable frames (so callers always get the most useful stack
* available).
*/
declare const getOwnerStack: (fiber: Fiber, shouldCache?: boolean, fetchFunction?: (url: string) => Promise<Response>) => Promise<StackFrame[]>;
//#endregion
//#region src/source/types.d.ts
interface FiberSource {
columnNumber?: number;
fileName: string;
lineNumber?: number;
functionName?: string;
}
//#endregion
//#region src/source/get-source.d.ts
/**
* Returns the source of where the component is used. Available only in dev, for composite {@link Fiber}s.
*
* Resolution order:
* 1. `_debugSource` (react <19, requires the JSX source babel transform)
* 2. the fiber's own `_debugStack` (react 19) - the exact JSX creation site
* 3. an owned child's `_debugStack` bottom frame (react 19) - a location
* inside the component's own body; works for components that the throwing
* trick cannot locate (no hooks, no props access)
* 4. the legacy owner-stack path (throwing trick re-invocation)
*
* @example
* ```ts
* function Parent() {
* const data = useData();
* return <Child name={data.name} />; // <-- captures THIS line
* }
*
* function Child({ name }) {
* return <div>{name}</div>;
* }
*
* const source = await getSource(fiber);
* console.log(source.fileName, source.lineNumber);
* ```
*/
declare const getSource: (fiber: Fiber, cache?: boolean, fetchFn?: (url: string) => Promise<Response>) => Promise<FiberSource | null>;
declare const normalizeFileName: (fileName: string) => string;
declare const isSourceFile: (fileName: string) => boolean;
//#endregion
//#region ../../node_modules/@jridgewell/sourcemap-codec/types/sourcemap-codec.d.mts
type SourceMapSegment = [number] | [number, number, number, number] | [number, number, number, number, number];
//#endregion
//#region src/source/symbolication.d.ts
interface DecodedSourceMapSection {
map: {
file?: string;
ignoredSourceIndices?: Set<number>;
mappings: SourceMapSegment[][];
names?: string[];
sourceRoot?: string;
sources: string[];
sourcesContent?: string[];
version: 3;
};
offset: {
column: number;
line: number;
};
}
interface IndexSourceMap {
file?: string;
sections: Array<{
map: StandardSourceMap;
offset: {
column: number;
line: number;
};
}>;
version: 3;
}
type RawSourceMap = IndexSourceMap | StandardSourceMap;
interface SourceMap {
file?: string;
ignoredSourceIndices?: Set<number>;
mappings: SourceMapSegment[][];
names?: string[];
sections?: DecodedSourceMapSection[];
sourceRoot?: string;
sources: string[];
sourcesContent?: string[];
version: 3;
}
interface StandardSourceMap {
file?: string;
ignoreList?: number[];
mappings: string;
names?: string[];
sourceRoot?: string;
sources: string[];
sourcesContent?: string[];
version: 3;
x_google_ignoreList?: number[];
}
declare const getSourceFromSourceMap: (sourceMap: SourceMap, line: number, column: number) => StackFrame | null;
declare const getSourceMap: (file: string, useCache?: boolean, fetchFn?: (url: string) => Promise<Response>) => Promise<null | SourceMap>;
declare const symbolicateStack: (stack: StackFrame[], cache?: boolean, fetchFn?: (url: string) => Promise<Response>) => Promise<StackFrame[]>;
//#endregion
//#region src/source/get-display-name-from-source.d.ts
declare const getDisplayNameFromSource: (fiber: Fiber, cache?: boolean, fetchFn?: (url: string) => Promise<Response>) => Promise<string | null>;
//#endregion
//#region src/source/inspect-hooks.d.ts
interface HookSource {
lineNumber: number | null;
columnNumber: number | null;
fileName: string | null;
functionName: string | null;
}
interface HooksNode {
id: number | null;
isStateEditable: boolean;
name: string;
value: unknown;
subHooks: HooksNode[];
hookSource: HookSource | null;
}
interface HooksTree extends Array<HooksNode> {}
declare const getFiberHooks: (fiber: Fiber) => HooksTree;
//#endregion
//#region src/source/parse-hook-names.d.ts
interface HookNames extends Map<string, string> {}
declare const parseHookNames: (hooksTree: HooksTree, fetchFn?: (url: string) => Promise<Response>) => Promise<HookNames>;
//#endregion
export { type DecodedSourceMapSection, type FiberSource, type HookNames, type HookSource, type HooksNode, type HooksTree, type IndexSourceMap, type ParseOptions, type RawSourceMap, type SourceMap, type StackFrame, type StandardSourceMap, formatOwnerStack, getDisplayNameFromSource, getFiberHooks, getOwnerStack, getParentStack, getSource, getSourceFromSourceMap, getSourceMap, hasDebugStack, isSourceFile, normalizeFileName, parseHookNames, parseStack, symbolicateStack };

14
node_modules/bippy/dist/source.js generated vendored Normal file

File diff suppressed because one or more lines are too long

298
node_modules/bippy/dist/unsubscribe.d.cts generated vendored Normal file
View File

@@ -0,0 +1,298 @@
import { ReactNode } from "react";
//#region src/types.d.ts
type BundleType = 0 | 1;
type Flags = number;
type Lanes = number;
type TypeOfMode = number;
type RootTag = 0 | 1 | 2;
type LanePriority = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17;
type WorkTag = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31;
type HookType = "useState" | "useReducer" | "useContext" | "useRef" | "useEffect" | "useLayoutEffect" | "useCallback" | "useMemo" | "useImperativeHandle" | "useDebugValue" | "useDeferredValue" | "useTransition" | "useMutableSource" | "useOpaqueIdentifier" | "useCacheRefresh";
type FiberRoot = any;
type MutableSource = any;
type OpaqueHandle = any;
type OpaqueRoot = any;
type React$AbstractComponent<_Config, _Instance = unknown> = any;
type HostConfig = Record<string, any>;
interface Source {
fileName: string;
lineNumber: number;
}
interface RefObject {
current: any;
}
interface Thenable<T> {
then(resolve: () => T, reject?: () => T): T;
}
interface ReactContext<T> {
$$typeof: symbol | number;
Consumer: ReactContext<T>;
Provider: ReactProviderType<T>;
_calculateChangedBits: ((a: T, b: T) => number) | null;
_currentValue: T;
_currentValue2: T;
_threadCount: number;
_currentRenderer?: Record<string, any> | null;
_currentRenderer2?: Record<string, any> | null;
displayName?: string;
}
interface ReactProviderType<T> {
$$typeof: symbol | number;
_context: ReactContext<T>;
}
interface ReactProvider<T> {
$$typeof: symbol | number;
type: ReactProviderType<T>;
key: null | string;
ref: null;
props: {
value: T;
children?: ReactNode;
};
}
interface ReactConsumer<T> {
$$typeof: symbol | number;
type: ReactContext<T>;
key: null | string;
ref: null;
props: {
children: (value: T) => ReactNode;
unstable_observedBits?: number;
};
}
interface ReactPortal {
$$typeof: symbol | number;
key: null | string;
containerInfo: any;
children: ReactNode;
implementation: any;
}
interface ComponentSelector {
$$typeof: symbol | number;
value: React$AbstractComponent<never, unknown>;
}
interface HasPseudoClassSelector {
$$typeof: symbol | number;
value: Selector[];
}
interface RoleSelector {
$$typeof: symbol | number;
value: string;
}
interface TextSelector {
$$typeof: symbol | number;
value: string;
}
interface TestNameSelector {
$$typeof: symbol | number;
value: string;
}
type Selector = ComponentSelector | HasPseudoClassSelector | RoleSelector | TextSelector | TestNameSelector;
interface DevToolsConfig<Instance = any, TextInstance = any, RendererInspectionConfig = any> {
bundleType: BundleType;
version: string;
rendererPackageName: string;
findFiberByHostInstance?: (instance: Instance | TextInstance) => ReactFiber | null;
rendererConfig?: RendererInspectionConfig;
}
interface SuspenseHydrationCallbacks<SuspenseInstance = unknown> {
onHydrated?: (suspenseInstance: SuspenseInstance) => void;
onDeleted?: (suspenseInstance: SuspenseInstance) => void;
}
interface TransitionTracingCallbacks {
onTransitionStart?: (transitionName: string, startTime: number) => void;
onTransitionProgress?: (transitionName: string, startTime: number, currentTime: number, pending: Array<{
name: null | string;
}>) => void;
onTransitionIncomplete?: (transitionName: string, startTime: number, deletions: Array<{
type: string;
name?: string;
newName?: string;
endTime: number;
}>) => void;
onTransitionComplete?: (transitionName: string, startTime: number, endTime: number) => void;
onMarkerProgress?: (transitionName: string, marker: string, startTime: number, currentTime: number, pending: Array<{
name: null | string;
}>) => void;
onMarkerIncomplete?: (transitionName: string, marker: string, startTime: number, deletions: Array<{
type: string;
name?: string;
newName?: string;
endTime: number;
}>) => void;
onMarkerComplete?: (transitionName: string, marker: string, startTime: number, endTime: number) => void;
}
interface ReactFiber {
tag: WorkTag;
key: null | string;
elementType: any;
type: any;
stateNode: any;
return: ReactFiber | null;
child: ReactFiber | null;
sibling: ReactFiber | null;
index: number;
ref: null | (((handle: unknown) => void) & {
_stringRef?: string | null;
}) | RefObject;
pendingProps: any;
memoizedProps: any;
updateQueue: unknown;
memoizedState: any;
dependencies: Dependencies | null;
mode: TypeOfMode;
flags: Flags;
subtreeFlags: Flags;
deletions: ReactFiber[] | null;
nextEffect: ReactFiber | null;
firstEffect: ReactFiber | null;
lastEffect: ReactFiber | null;
lanes: Lanes;
childLanes: Lanes;
alternate: ReactFiber | null;
actualDuration?: number;
actualStartTime?: number;
selfBaseDuration?: number;
treeBaseDuration?: number;
_debugID?: number;
_debugSource?: Source | null;
_debugOwner?: ReactFiber | null;
_debugIsCurrentlyTiming?: boolean;
_debugNeedsRemount?: boolean;
_debugHookTypes?: HookType[] | null;
}
interface ContextDependency<T> {
context: ReactContext<T>;
memoizedValue: T;
next: ContextDependency<unknown> | null;
observedBits: number;
}
interface Dependencies {
firstContext: ContextDependency<unknown> | null;
lanes: Lanes;
}
interface Effect {
[key: string]: unknown;
create: (...args: unknown[]) => unknown;
deps: null | unknown[];
destroy: ((...args: unknown[]) => unknown) | null;
next: Effect | null;
tag: number;
}
interface Family {
current: unknown;
}
/**
* React 19 flight metadata for a server component owner (ReactComponentInfo).
* Unlike client owners it has no `tag`; the owner chain continues via `owner`.
*/
interface ServerComponentInfo {
name?: string;
env?: string;
owner?: Fiber | ServerComponentInfo | null;
debugStack?: Error | null;
}
interface RendererRefreshUpdate {
staleFamilies: Set<Family>;
updatedFamilies: Set<Family>;
}
/**
* Represents a react-internal Fiber node.
*/
type Fiber<T = any> = Omit<ReactFiber, "alternate" | "child" | "dependencies" | "memoizedProps" | "memoizedState" | "pendingProps" | "return" | "sibling" | "stateNode" | "updateQueue"> & {
_debugInfo?: Array<{
debugLocation?: unknown;
env?: string;
name?: string;
}>;
_debugOwner?: Fiber;
_debugSource?: {
columnNumber?: number;
fileName: string;
lineNumber: number;
};
_debugStack?: Error & {
stack: string;
};
alternate: Fiber | null;
child: Fiber | null;
dependencies: Dependencies | null;
memoizedProps: Props;
memoizedState: MemoizedState;
pendingProps: Props;
return: Fiber | null;
sibling: Fiber | null;
stateNode: T;
updateQueue: {
[key: string]: unknown;
lastEffect: Effect | null;
};
};
interface MemoizedState {
[key: string]: unknown;
memoizedState: unknown;
next: MemoizedState | null;
}
interface Props {
[key: string]: unknown;
}
interface ReactDevToolsGlobalHook {
_instrumentationIsActive?: boolean;
_instrumentationSource?: string;
checkDCE: (fn: unknown) => void;
hasUnsupportedRendererAttached: boolean;
inject: (renderer: ReactRenderer) => number;
on: () => void;
onCommitFiberRoot: (rendererID: number, root: FiberRoot, priority: number | void) => void;
onCommitFiberUnmount: (rendererID: number, fiber: Fiber) => void;
onPostCommitFiberRoot: (rendererID: number, root: FiberRoot) => void;
onScheduleFiberRoot?: (rendererID: number, root: FiberRoot, children: ReactNode) => void;
renderers: Map<number, ReactRenderer>;
supportsFiber: boolean;
supportsFlight: boolean;
}
interface ReactRenderer {
bundleType: 0 | 1;
currentDispatcherRef: any;
findFiberByHostInstance?: (hostInstance: unknown) => Fiber | null;
getCurrentFiber?: (fiber: Fiber) => Fiber | null;
overrideContext?: (fiber: Fiber, contextType: unknown, path: string[], value: unknown) => void;
overrideHookState?: (fiber: Fiber, id: string, path: string[], value: unknown) => void;
overrideHookStateDeletePath?: (fiber: Fiber, id: number, path: Array<number | string>) => void;
overrideHookStateRenamePath?: (fiber: Fiber, id: number, oldPath: Array<number | string>, newPath: Array<number | string>) => void;
overrideProps?: (fiber: Fiber, path: string[], value: unknown) => void;
overridePropsDeletePath?: (fiber: Fiber, path: Array<number | string>) => void;
overridePropsRenamePath?: (fiber: Fiber, oldPath: Array<number | string>, newPath: Array<number | string>) => void;
reconcilerVersion: string;
rendererPackageName: string;
scheduleRefresh?: (root: FiberRoot, update: RendererRefreshUpdate) => void;
scheduleRoot?: (root: FiberRoot, element: React.ReactNode) => void;
scheduleUpdate?: (fiber: Fiber) => void;
setErrorHandler?: (newShouldErrorImpl: (fiber: Fiber) => boolean) => void;
setRefreshHandler?: (handler: ((fiber: Fiber) => Family | null) | null) => void;
setSuspenseHandler?: (newShouldSuspendImpl: (suspenseInstance: unknown) => void) => void;
version: string;
}
declare global {
var __REACT_DEVTOOLS_GLOBAL_HOOK__: ReactDevToolsGlobalHook | undefined;
}
//#endregion
//#region src/unsubscribe.d.ts
interface Unsubscribe extends Disposable {
(): void;
}
/**
* Wraps a teardown callback so it is both callable and a `Disposable`,
* letting subscriptions compose through explicit resource management:
*
* @example
* ```ts
* using instrumentation = instrument({ onCommitFiberRoot });
* using refresh = instrumentReactRefresh({ onRefresh: handleRefresh });
* // both torn down automatically at scope exit
* ```
*/
declare const toUnsubscribe: (dispose: () => void) => Unsubscribe;
//#endregion
export { ReactRenderer as A, TextSelector as B, React$AbstractComponent as C, ReactPortal as D, ReactDevToolsGlobalHook as E, Selector as F, TransitionTracingCallbacks as H, ServerComponentInfo as I, Source as L, RendererRefreshUpdate as M, RoleSelector as N, ReactProvider as O, RootTag as P, SuspenseHydrationCallbacks as R, Props as S, ReactContext as T, TypeOfMode as U, Thenable as V, WorkTag as W, Lanes as _, ContextDependency as a, OpaqueHandle as b, Effect as c, FiberRoot as d, Flags as f, LanePriority as g, HostConfig as h, ComponentSelector as i, RefObject as j, ReactProviderType as k, Family as l, HookType as m, toUnsubscribe as n, Dependencies as o, HasPseudoClassSelector as p, BundleType as r, DevToolsConfig as s, Unsubscribe as t, Fiber as u, MemoizedState as v, ReactConsumer as w, OpaqueRoot as x, MutableSource as y, TestNameSelector as z };

298
node_modules/bippy/dist/unsubscribe.d.ts generated vendored Normal file
View File

@@ -0,0 +1,298 @@
import { ReactNode } from "react";
//#region src/types.d.ts
type BundleType = 0 | 1;
type Flags = number;
type Lanes = number;
type TypeOfMode = number;
type RootTag = 0 | 1 | 2;
type LanePriority = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17;
type WorkTag = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31;
type HookType = "useState" | "useReducer" | "useContext" | "useRef" | "useEffect" | "useLayoutEffect" | "useCallback" | "useMemo" | "useImperativeHandle" | "useDebugValue" | "useDeferredValue" | "useTransition" | "useMutableSource" | "useOpaqueIdentifier" | "useCacheRefresh";
type FiberRoot = any;
type MutableSource = any;
type OpaqueHandle = any;
type OpaqueRoot = any;
type React$AbstractComponent<_Config, _Instance = unknown> = any;
type HostConfig = Record<string, any>;
interface Source {
fileName: string;
lineNumber: number;
}
interface RefObject {
current: any;
}
interface Thenable<T> {
then(resolve: () => T, reject?: () => T): T;
}
interface ReactContext<T> {
$$typeof: symbol | number;
Consumer: ReactContext<T>;
Provider: ReactProviderType<T>;
_calculateChangedBits: ((a: T, b: T) => number) | null;
_currentValue: T;
_currentValue2: T;
_threadCount: number;
_currentRenderer?: Record<string, any> | null;
_currentRenderer2?: Record<string, any> | null;
displayName?: string;
}
interface ReactProviderType<T> {
$$typeof: symbol | number;
_context: ReactContext<T>;
}
interface ReactProvider<T> {
$$typeof: symbol | number;
type: ReactProviderType<T>;
key: null | string;
ref: null;
props: {
value: T;
children?: ReactNode;
};
}
interface ReactConsumer<T> {
$$typeof: symbol | number;
type: ReactContext<T>;
key: null | string;
ref: null;
props: {
children: (value: T) => ReactNode;
unstable_observedBits?: number;
};
}
interface ReactPortal {
$$typeof: symbol | number;
key: null | string;
containerInfo: any;
children: ReactNode;
implementation: any;
}
interface ComponentSelector {
$$typeof: symbol | number;
value: React$AbstractComponent<never, unknown>;
}
interface HasPseudoClassSelector {
$$typeof: symbol | number;
value: Selector[];
}
interface RoleSelector {
$$typeof: symbol | number;
value: string;
}
interface TextSelector {
$$typeof: symbol | number;
value: string;
}
interface TestNameSelector {
$$typeof: symbol | number;
value: string;
}
type Selector = ComponentSelector | HasPseudoClassSelector | RoleSelector | TextSelector | TestNameSelector;
interface DevToolsConfig<Instance = any, TextInstance = any, RendererInspectionConfig = any> {
bundleType: BundleType;
version: string;
rendererPackageName: string;
findFiberByHostInstance?: (instance: Instance | TextInstance) => ReactFiber | null;
rendererConfig?: RendererInspectionConfig;
}
interface SuspenseHydrationCallbacks<SuspenseInstance = unknown> {
onHydrated?: (suspenseInstance: SuspenseInstance) => void;
onDeleted?: (suspenseInstance: SuspenseInstance) => void;
}
interface TransitionTracingCallbacks {
onTransitionStart?: (transitionName: string, startTime: number) => void;
onTransitionProgress?: (transitionName: string, startTime: number, currentTime: number, pending: Array<{
name: null | string;
}>) => void;
onTransitionIncomplete?: (transitionName: string, startTime: number, deletions: Array<{
type: string;
name?: string;
newName?: string;
endTime: number;
}>) => void;
onTransitionComplete?: (transitionName: string, startTime: number, endTime: number) => void;
onMarkerProgress?: (transitionName: string, marker: string, startTime: number, currentTime: number, pending: Array<{
name: null | string;
}>) => void;
onMarkerIncomplete?: (transitionName: string, marker: string, startTime: number, deletions: Array<{
type: string;
name?: string;
newName?: string;
endTime: number;
}>) => void;
onMarkerComplete?: (transitionName: string, marker: string, startTime: number, endTime: number) => void;
}
interface ReactFiber {
tag: WorkTag;
key: null | string;
elementType: any;
type: any;
stateNode: any;
return: ReactFiber | null;
child: ReactFiber | null;
sibling: ReactFiber | null;
index: number;
ref: null | (((handle: unknown) => void) & {
_stringRef?: string | null;
}) | RefObject;
pendingProps: any;
memoizedProps: any;
updateQueue: unknown;
memoizedState: any;
dependencies: Dependencies | null;
mode: TypeOfMode;
flags: Flags;
subtreeFlags: Flags;
deletions: ReactFiber[] | null;
nextEffect: ReactFiber | null;
firstEffect: ReactFiber | null;
lastEffect: ReactFiber | null;
lanes: Lanes;
childLanes: Lanes;
alternate: ReactFiber | null;
actualDuration?: number;
actualStartTime?: number;
selfBaseDuration?: number;
treeBaseDuration?: number;
_debugID?: number;
_debugSource?: Source | null;
_debugOwner?: ReactFiber | null;
_debugIsCurrentlyTiming?: boolean;
_debugNeedsRemount?: boolean;
_debugHookTypes?: HookType[] | null;
}
interface ContextDependency<T> {
context: ReactContext<T>;
memoizedValue: T;
next: ContextDependency<unknown> | null;
observedBits: number;
}
interface Dependencies {
firstContext: ContextDependency<unknown> | null;
lanes: Lanes;
}
interface Effect {
[key: string]: unknown;
create: (...args: unknown[]) => unknown;
deps: null | unknown[];
destroy: ((...args: unknown[]) => unknown) | null;
next: Effect | null;
tag: number;
}
interface Family {
current: unknown;
}
/**
* React 19 flight metadata for a server component owner (ReactComponentInfo).
* Unlike client owners it has no `tag`; the owner chain continues via `owner`.
*/
interface ServerComponentInfo {
name?: string;
env?: string;
owner?: Fiber | ServerComponentInfo | null;
debugStack?: Error | null;
}
interface RendererRefreshUpdate {
staleFamilies: Set<Family>;
updatedFamilies: Set<Family>;
}
/**
* Represents a react-internal Fiber node.
*/
type Fiber<T = any> = Omit<ReactFiber, "alternate" | "child" | "dependencies" | "memoizedProps" | "memoizedState" | "pendingProps" | "return" | "sibling" | "stateNode" | "updateQueue"> & {
_debugInfo?: Array<{
debugLocation?: unknown;
env?: string;
name?: string;
}>;
_debugOwner?: Fiber;
_debugSource?: {
columnNumber?: number;
fileName: string;
lineNumber: number;
};
_debugStack?: Error & {
stack: string;
};
alternate: Fiber | null;
child: Fiber | null;
dependencies: Dependencies | null;
memoizedProps: Props;
memoizedState: MemoizedState;
pendingProps: Props;
return: Fiber | null;
sibling: Fiber | null;
stateNode: T;
updateQueue: {
[key: string]: unknown;
lastEffect: Effect | null;
};
};
interface MemoizedState {
[key: string]: unknown;
memoizedState: unknown;
next: MemoizedState | null;
}
interface Props {
[key: string]: unknown;
}
interface ReactDevToolsGlobalHook {
_instrumentationIsActive?: boolean;
_instrumentationSource?: string;
checkDCE: (fn: unknown) => void;
hasUnsupportedRendererAttached: boolean;
inject: (renderer: ReactRenderer) => number;
on: () => void;
onCommitFiberRoot: (rendererID: number, root: FiberRoot, priority: number | void) => void;
onCommitFiberUnmount: (rendererID: number, fiber: Fiber) => void;
onPostCommitFiberRoot: (rendererID: number, root: FiberRoot) => void;
onScheduleFiberRoot?: (rendererID: number, root: FiberRoot, children: ReactNode) => void;
renderers: Map<number, ReactRenderer>;
supportsFiber: boolean;
supportsFlight: boolean;
}
interface ReactRenderer {
bundleType: 0 | 1;
currentDispatcherRef: any;
findFiberByHostInstance?: (hostInstance: unknown) => Fiber | null;
getCurrentFiber?: (fiber: Fiber) => Fiber | null;
overrideContext?: (fiber: Fiber, contextType: unknown, path: string[], value: unknown) => void;
overrideHookState?: (fiber: Fiber, id: string, path: string[], value: unknown) => void;
overrideHookStateDeletePath?: (fiber: Fiber, id: number, path: Array<number | string>) => void;
overrideHookStateRenamePath?: (fiber: Fiber, id: number, oldPath: Array<number | string>, newPath: Array<number | string>) => void;
overrideProps?: (fiber: Fiber, path: string[], value: unknown) => void;
overridePropsDeletePath?: (fiber: Fiber, path: Array<number | string>) => void;
overridePropsRenamePath?: (fiber: Fiber, oldPath: Array<number | string>, newPath: Array<number | string>) => void;
reconcilerVersion: string;
rendererPackageName: string;
scheduleRefresh?: (root: FiberRoot, update: RendererRefreshUpdate) => void;
scheduleRoot?: (root: FiberRoot, element: React.ReactNode) => void;
scheduleUpdate?: (fiber: Fiber) => void;
setErrorHandler?: (newShouldErrorImpl: (fiber: Fiber) => boolean) => void;
setRefreshHandler?: (handler: ((fiber: Fiber) => Family | null) | null) => void;
setSuspenseHandler?: (newShouldSuspendImpl: (suspenseInstance: unknown) => void) => void;
version: string;
}
declare global {
var __REACT_DEVTOOLS_GLOBAL_HOOK__: ReactDevToolsGlobalHook | undefined;
}
//#endregion
//#region src/unsubscribe.d.ts
interface Unsubscribe extends Disposable {
(): void;
}
/**
* Wraps a teardown callback so it is both callable and a `Disposable`,
* letting subscriptions compose through explicit resource management:
*
* @example
* ```ts
* using instrumentation = instrument({ onCommitFiberRoot });
* using refresh = instrumentReactRefresh({ onRefresh: handleRefresh });
* // both torn down automatically at scope exit
* ```
*/
declare const toUnsubscribe: (dispose: () => void) => Unsubscribe;
//#endregion
export { ReactRenderer as A, TextSelector as B, React$AbstractComponent as C, ReactPortal as D, ReactDevToolsGlobalHook as E, Selector as F, TransitionTracingCallbacks as H, ServerComponentInfo as I, Source as L, RendererRefreshUpdate as M, RoleSelector as N, ReactProvider as O, RootTag as P, SuspenseHydrationCallbacks as R, Props as S, ReactContext as T, TypeOfMode as U, Thenable as V, WorkTag as W, Lanes as _, ContextDependency as a, OpaqueHandle as b, Effect as c, FiberRoot as d, Flags as f, LanePriority as g, HostConfig as h, ComponentSelector as i, RefObject as j, ReactProviderType as k, Family as l, HookType as m, toUnsubscribe as n, Dependencies as o, HasPseudoClassSelector as p, BundleType as r, DevToolsConfig as s, Unsubscribe as t, Fiber as u, MemoizedState as v, ReactConsumer as w, OpaqueRoot as x, MutableSource as y, TestNameSelector as z };

133
node_modules/bippy/package.json generated vendored Normal file
View File

@@ -0,0 +1,133 @@
{
"name": "bippy",
"version": "0.6.1",
"description": "hack into react internals",
"keywords": [
"bippy",
"fiber",
"internals",
"react",
"react devtools",
"react fiber",
"react instrumentation"
],
"homepage": "https://bippy.dev",
"bugs": {
"url": "https://github.com/aidenybai/bippy/issues"
},
"license": "MIT",
"author": {
"name": "Aiden Bai",
"email": "aiden@million.dev"
},
"repository": {
"type": "git",
"url": "git+https://github.com/aidenybai/bippy.git"
},
"files": [
"dist",
"src",
"package.json",
"README.md",
"LICENSE"
],
"type": "module",
"main": "dist/index.js",
"module": "dist/index.js",
"browser": "dist/index.iife.js",
"types": "dist/index.d.ts",
"exports": {
"./package.json": "./package.json",
".": {
"import": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"require": {
"types": "./dist/index.d.cts",
"default": "./dist/index.cjs"
}
},
"./core": {
"import": {
"types": "./dist/core.d.ts",
"default": "./dist/core.js"
},
"require": {
"types": "./dist/core.d.cts",
"default": "./dist/core.cjs"
}
},
"./install-hook-only": {
"import": {
"types": "./dist/install-hook-only.d.ts",
"default": "./dist/install-hook-only.js"
},
"require": {
"types": "./dist/install-hook-only.d.cts",
"default": "./dist/install-hook-only.cjs"
}
},
"./source": {
"import": {
"types": "./dist/source.d.ts",
"default": "./dist/source.js"
},
"require": {
"types": "./dist/source.d.cts",
"default": "./dist/source.cjs"
}
},
"./react-refresh": {
"import": {
"types": "./dist/react-refresh.d.ts",
"default": "./dist/react-refresh.js"
},
"require": {
"types": "./dist/react-refresh.d.cts",
"default": "./dist/react-refresh.cjs"
}
},
"./dist/*": "./dist/*.js",
"./dist/*.js": "./dist/*.js",
"./dist/*.cjs": "./dist/*.cjs"
},
"publishConfig": {
"access": "public"
},
"devDependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0",
"@react-pdf/renderer": "^4.5.1",
"@react-three/fiber": "^9.6.1",
"@react-three/test-renderer": "^9.1.0",
"@testing-library/dom": "^10.4.0",
"@testing-library/react": "^16.1.0",
"@types/node": "^20",
"@types/react": "^19.2.17",
"@types/react-dom": "^19.2.3",
"@vitest/coverage-istanbul": "^4.1.10",
"happy-dom": "^15.11.7",
"ink": "^7.1.1",
"ink-testing-library": "^4.0.0",
"publint": "^0.3.0",
"react": "19.0.0",
"react-devtools-inline": "^6.0.1",
"react-dom": "19.0.0",
"react-nil": "^2.0.0",
"react-refresh": "^0.16.0",
"remotion": "^4.0.496",
"three": "^0.185.1",
"tsx": "^4.21.0",
"vite-plus": "latest"
},
"peerDependencies": {
"react": ">=17.0.1"
},
"scripts": {
"build": "NODE_ENV=production vp pack && tsx scripts/append-banner.ts",
"dev": "NODE_ENV=development vp pack --watch",
"publint": "publint",
"test": "vp test",
"coverage": "vp test --coverage"
}
}

1261
node_modules/bippy/src/core.ts generated vendored Normal file

File diff suppressed because it is too large Load Diff

3
node_modules/bippy/src/index.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import "./install-hook-only.js";
export * from "./core.js";

3
node_modules/bippy/src/install-hook-only.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import { safelyInstallRDTHook } from "./rdt-hook.js";
safelyInstallRDTHook();

270
node_modules/bippy/src/rdt-hook.ts generated vendored Normal file
View File

@@ -0,0 +1,270 @@
// IMPORTANT:
// this file is super important to load the __REACT_DEVTOOLS_GLOBAL_HOOK__ object
// without this, we can't stub the React DevTools global hook, we don't have a way to instrument the application
// make sure you import this file first before anything else (particularly React)
import type { ReactDevToolsGlobalHook, ReactRenderer } from "./types.js";
import { toUnsubscribe, type Unsubscribe } from "./unsubscribe.js";
export const version = process.env.VERSION;
export const BIPPY_INSTRUMENTATION_STRING = `bippy-${version}`;
const objectDefineProperty = Object.defineProperty;
// eslint-disable-next-line @typescript-eslint/unbound-method
const objectHasOwnProperty = Object.prototype.hasOwnProperty;
const NO_OP = () => {
/**/
};
const checkDCE = (functionToCheck: unknown): void => {
try {
const code = Function.prototype.toString.call(functionToCheck);
if (code.indexOf("^_^") > -1) {
setTimeout(() => {
throw new Error(
"React is running in production mode, but dead code " +
"elimination has not been applied. Read how to correctly " +
"configure React for production: " +
"https://reactjs.org/link/perf-use-production-build",
);
});
}
} catch {}
};
export const isRealReactDevtools = (
rdtHook: ReactDevToolsGlobalHook | undefined | null = globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__,
): boolean => {
return Boolean(rdtHook && "getFiberRoots" in rdtHook);
};
let isReactRefreshOverride = false;
let injectFnStr: string | undefined = undefined;
export const isReactRefresh = (
rdtHook: ReactDevToolsGlobalHook | undefined | null = globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__,
): boolean => {
if (isReactRefreshOverride) return true;
if (rdtHook && typeof rdtHook.inject === "function") {
injectFnStr = rdtHook.inject.toString();
}
// https://github.com/facebook/react/blob/8f8b336734d7c807f5aa11b0f31540e63302d789/packages/react-refresh/src/ReactFreshRuntime.js#L459
return Boolean(injectFnStr?.includes("(injected)"));
};
export const _onActiveListeners = new Set<() => unknown>();
export const _renderers = new Set<ReactRenderer>();
const rendererInjectListeners = new Set<(renderer: ReactRenderer) => void>();
// re-wrapping inject (e.g. after the hook is replaced) leaves the old
// wrapper in the call chain, so notifications are deduped per renderer
const notifiedRenderers = new WeakSet<ReactRenderer>();
let notifyingInject: ReactDevToolsGlobalHook["inject"] | null = null;
const ensureInjectNotifiesListeners = (rdtHook: ReactDevToolsGlobalHook): void => {
if (rdtHook.inject === notifyingInject) return;
const prevInject = rdtHook.inject;
const nextInject = (renderer: ReactRenderer) => {
const rendererId = prevInject.call(rdtHook, renderer);
if (!notifiedRenderers.has(renderer)) {
notifiedRenderers.add(renderer);
for (const listener of rendererInjectListeners) {
listener(renderer);
}
}
return rendererId;
};
rdtHook.inject = nextInject;
notifyingInject = nextInject;
};
/**
* Subscribes to future renderer injections into the DevTools hook. The
* single shared inject wrapper lets multiple consumers (override methods,
* react-refresh, user code) observe renderers without stacking patches
* whose restore order matters. Returns an unsubscribe function.
*/
export const onRendererInject = (listener: (renderer: ReactRenderer) => void): Unsubscribe => {
ensureInjectNotifiesListeners(getRDTHook());
rendererInjectListeners.add(listener);
return toUnsubscribe(() => {
rendererInjectListeners.delete(listener);
});
};
export const installRDTHook = (onActive?: () => unknown): ReactDevToolsGlobalHook => {
if (onActive) {
_onActiveListeners.add(onActive);
}
const renderers = new Map<number, ReactRenderer>();
let rendererIdCounter = 0;
let rdtHook: ReactDevToolsGlobalHook = {
_instrumentationIsActive: false,
_instrumentationSource: BIPPY_INSTRUMENTATION_STRING,
checkDCE,
hasUnsupportedRendererAttached: false,
inject(renderer) {
const nextRendererId = ++rendererIdCounter;
renderers.set(nextRendererId, renderer);
_renderers.add(renderer);
if (!rdtHook._instrumentationIsActive) {
rdtHook._instrumentationIsActive = true;
_onActiveListeners.forEach((listener) => listener());
}
return nextRendererId;
},
on: NO_OP,
onCommitFiberRoot: NO_OP,
onCommitFiberUnmount: NO_OP,
onPostCommitFiberRoot: NO_OP,
renderers,
supportsFiber: true,
supportsFlight: true,
};
try {
objectDefineProperty(globalThis, "__REACT_DEVTOOLS_GLOBAL_HOOK__", {
configurable: true,
enumerable: true,
get() {
return rdtHook;
},
set(newHook) {
if (newHook && typeof newHook === "object") {
const ourRenderers = rdtHook.renderers;
rdtHook = newHook;
if (ourRenderers.size > 0) {
ourRenderers.forEach((renderer, id) => {
_renderers.add(renderer);
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
newHook.renderers.set(id, renderer);
});
patchRDTHook(onActive);
}
}
},
});
// [!] this is a hack for chrome extensions - if we install before React DevTools, we could accidently prevent React DevTools from installing:
// https://github.com/facebook/react/blob/18eaf51bd51fed8dfed661d64c306759101d0bfd/packages/react-devtools-extensions/src/contentScripts/installHook.js#L30C6-L30C27
// eslint-disable-next-line @typescript-eslint/unbound-method
const originalWindowHasOwnProperty = window.hasOwnProperty;
let hasRanHack = false;
objectDefineProperty(window, "hasOwnProperty", {
configurable: true,
value: function (this: unknown, ...args: [PropertyKey]) {
try {
if (!hasRanHack && args[0] === "__REACT_DEVTOOLS_GLOBAL_HOOK__") {
globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__ = undefined;
// special falsy value to know that we've already installed before
hasRanHack = true;
return -0;
}
} catch {}
return originalWindowHasOwnProperty.apply(this, args);
},
writable: true,
});
} catch {
patchRDTHook(onActive);
}
return rdtHook;
};
export const patchRDTHook = (onActive?: () => unknown): void => {
if (onActive) {
_onActiveListeners.add(onActive);
}
try {
const rdtHook = globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__;
if (!rdtHook) return;
if (!rdtHook._instrumentationSource) {
rdtHook.checkDCE = checkDCE;
rdtHook.supportsFiber = true;
rdtHook.supportsFlight = true;
rdtHook.hasUnsupportedRendererAttached = false;
rdtHook._instrumentationSource = BIPPY_INSTRUMENTATION_STRING;
rdtHook._instrumentationIsActive = false;
// we need to be careful here (needs to be below _instrumentationSource) else it causes excessive recursion
const isReactDevtools = isRealReactDevtools(rdtHook);
if (!isReactDevtools) {
rdtHook.on = NO_OP;
}
if (rdtHook.renderers.size) {
rdtHook._instrumentationIsActive = true;
_onActiveListeners.forEach((listener) => listener());
return;
}
const prevInject = rdtHook.inject;
const isRefresh = isReactRefresh(rdtHook);
if (isRefresh && !isReactDevtools) {
isReactRefreshOverride = true;
// but since the underlying implementation doens't care,
// it's ok: https://github.com/facebook/react/blob/18eaf51bd51fed8dfed661d64c306759101d0bfd/packages/react-refresh/src/ReactFreshRuntime.js#L430
const injectedRendererId = rdtHook.inject({
scheduleRefresh() {},
} as unknown as ReactRenderer);
if (injectedRendererId) {
rdtHook._instrumentationIsActive = true;
}
}
rdtHook.inject = (renderer) => {
const rendererId = prevInject(renderer);
_renderers.add(renderer);
if (isRefresh) {
// react refresh doesn't inject this properly
// https://github.com/facebook/react/blob/18eaf51bd51fed8dfed661d64c306759101d0bfd/packages/react-refresh/src/ReactFreshRuntime.js#L430
rdtHook.renderers.set(rendererId, renderer);
}
rdtHook._instrumentationIsActive = true;
_onActiveListeners.forEach((listener) => listener());
return rendererId;
};
}
if (
rdtHook.renderers.size ||
rdtHook._instrumentationIsActive ||
// depending on this to inject is unsafe, since inject could occur before and we wouldn't know
isReactRefresh()
) {
onActive?.();
}
} catch {}
};
export const hasRDTHook = (): boolean => {
return objectHasOwnProperty.call(globalThis, "__REACT_DEVTOOLS_GLOBAL_HOOK__");
};
/**
* Returns the current React DevTools global hook.
*/
export const getRDTHook = (onActive?: () => unknown): ReactDevToolsGlobalHook => {
if (!hasRDTHook()) {
return installRDTHook(onActive);
}
patchRDTHook(onActive);
// must exist at this point
return globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__ as ReactDevToolsGlobalHook;
};
export const isClientEnvironment = (): boolean => {
return Boolean(
typeof window !== "undefined" &&
// eslint-disable-next-line @typescript-eslint/unbound-method
(window.document?.createElement || window.navigator?.product === "ReactNative"),
);
};
/**
* Usually used purely for side effect
*/
export const safelyInstallRDTHook = () => {
try {
// __REACT_DEVTOOLS_GLOBAL_HOOK__ must exist before React is ever executed
if (isClientEnvironment()) {
getRDTHook();
}
} catch {}
};

9
node_modules/bippy/src/react-refresh/constants.ts generated vendored Normal file
View File

@@ -0,0 +1,9 @@
export const HMR_RECONNECT_DELAY_MS = 1000;
export const PENDING_HOT_UPDATE_MAX_AGE_MS = 10_000;
export const VITE_WS_TOKEN_REGEX = /wsToken = "([^"]+)"/;
export const HMR_SOURCE_FILE_EXTENSION_REGEX = /\.(?:tsx|ts|jsx|js|mjs|cjs|css)$/;
export const BUNDLER_LAYER_PREFIX_REGEX = /^(?:\.\/)?\/?\([a-z][a-z0-9-]*\)\//;

View File

@@ -0,0 +1,33 @@
import { isClientEnvironment } from "../rdt-hook.js";
import { createMetroHmrTransport } from "./metro-hmr-transport.js";
import { createNextWebpackHmrTransport } from "./next-webpack-hmr-transport.js";
import { HmrTransport, HmrUpdateHandler } from "./types.js";
import { createViteHmrTransport } from "./vite-hmr-transport.js";
/**
* Detects the dev server's HMR transport (Next.js webpack, then Metro for
* React Native, then Vite) and subscribes `onHmrUpdate` to hot updates.
* Resolves `null` on the server (SSR) and when no known transport is
* available (production builds, unsupported bundlers — Turbopack exposes
* `window.TURBOPACK_CHUNK_UPDATE_LISTENERS` but its update payload shape
* has not been validated, so it is not wired up yet).
*
* @example
* ```ts
* const transport = await detectHmrTransport((filePaths) => {
* console.log("hot updated:", filePaths);
* });
* transport?.dispose();
* ```
*/
export const detectHmrTransport = async (
onHmrUpdate: HmrUpdateHandler,
): Promise<HmrTransport | null> => {
if (!isClientEnvironment()) return null;
const webpackTransport = createNextWebpackHmrTransport(onHmrUpdate);
if (webpackTransport) return webpackTransport;
const metroTransport = createMetroHmrTransport(onHmrUpdate);
if (metroTransport) return metroTransport;
return createViteHmrTransport(onHmrUpdate);
};

173
node_modules/bippy/src/react-refresh/index.ts generated vendored Normal file
View File

@@ -0,0 +1,173 @@
import { getType, traverseFiber } from "../core.js";
import { getRDTHook, isClientEnvironment, onRendererInject } from "../rdt-hook.js";
import type { Fiber, FiberRoot, ReactRenderer } from "../types.js";
import { toUnsubscribe, type Unsubscribe } from "../unsubscribe.js";
import { PENDING_HOT_UPDATE_MAX_AGE_MS } from "./constants.js";
import { detectHmrTransport } from "./detect-hmr-transport.js";
import { HmrTransport } from "./types.js";
export interface ReactRefreshUpdate {
/**
* hot-updated source file paths reported by the bundler's HMR transport
* (auto-detected: Next.js webpack, Metro, Vite). Best-effort: empty when
* the bundler does not expose a transport (e.g. Turbopack) or when the
* transport message has not arrived yet (e.g. Metro delivers updates on
* an independent socket).
*/
filePaths: string[];
root: FiberRoot;
/** new component types that were remounted, losing state */
staleComponents: unknown[];
/** mounted fibers whose component types were remounted */
staleFibers: Fiber[];
/** new component types that re-rendered preserving state */
updatedComponents: unknown[];
/** mounted fibers whose component types re-rendered preserving state */
updatedFibers: Fiber[];
}
export interface ReactRefreshHandler {
(update: ReactRefreshUpdate): void;
}
export interface ReactRefreshInstrumentationOptions {
onRefresh?: ReactRefreshHandler;
}
const collectFibersByComponentType = (root: FiberRoot, componentTypes: Set<unknown>): Fiber[] => {
if (componentTypes.size === 0 || !root.current) return [];
const matchedFibers: Fiber[] = [];
traverseFiber(root.current, (fiber) => {
// memo/forwardRef fibers carry the wrapper as fiber.type, while the
// refresh families can register either the wrapper or the inner type
if (componentTypes.has(fiber.type) || componentTypes.has(getType(fiber.type))) {
matchedFibers.push(fiber);
}
});
return matchedFibers;
};
const refreshHandlers = new Set<ReactRefreshHandler>();
const refreshWrappedRenderers = new WeakSet<ReactRenderer>();
let pendingFilePaths: string[] = [];
let pendingFilePathsReceivedAtMs = 0;
const bufferHotUpdateFilePaths = (filePaths: string[]): void => {
const nowMs = Date.now();
if (nowMs - pendingFilePathsReceivedAtMs > PENDING_HOT_UPDATE_MAX_AGE_MS) {
pendingFilePaths = [];
}
pendingFilePaths.push(...filePaths);
pendingFilePathsReceivedAtMs = nowMs;
};
const takeFreshFilePaths = (): string[] => {
if (Date.now() - pendingFilePathsReceivedAtMs > PENDING_HOT_UPDATE_MAX_AGE_MS) return [];
const freshFilePaths = [...pendingFilePaths];
// performReactRefresh calls scheduleRefresh synchronously once per
// mounted root, so clear the pending paths only after the whole
// refresh pass instead of on the first root
queueMicrotask(() => {
pendingFilePaths = [];
});
return freshFilePaths;
};
const wrapRendererScheduleRefresh = (renderer: ReactRenderer): void => {
if (refreshWrappedRenderers.has(renderer)) return;
const originalScheduleRefresh = renderer.scheduleRefresh;
if (typeof originalScheduleRefresh !== "function") return;
refreshWrappedRenderers.add(renderer);
renderer.scheduleRefresh = (root, update) => {
originalScheduleRefresh.call(renderer, root, update);
if (refreshHandlers.size === 0) return;
const staleComponents = Array.from(update.staleFamilies, (family) => family.current);
const updatedComponents = Array.from(update.updatedFamilies, (family) => family.current);
const refreshUpdate: ReactRefreshUpdate = {
filePaths: takeFreshFilePaths(),
root,
staleComponents,
staleFibers: collectFibersByComponentType(root, new Set(staleComponents)),
updatedComponents,
updatedFibers: collectFibersByComponentType(root, new Set(updatedComponents)),
};
for (const handler of refreshHandlers) {
handler(refreshUpdate);
}
};
};
let isRefreshWired = false;
const ensureRefreshWired = (): void => {
if (isRefreshWired) return;
isRefreshWired = true;
const rdtHook = getRDTHook();
for (const renderer of rdtHook.renderers.values()) {
wrapRendererScheduleRefresh(renderer);
}
onRendererInject(wrapRendererScheduleRefresh);
};
let activeTransport: HmrTransport | null = null;
// the bundler's HMR global may not exist yet when an early subscriber
// arrives, so detection is retried whenever the first subscriber (re)appears
const detectTransportForNewSubscriber = (): void => {
void detectHmrTransport(bufferHotUpdateFilePaths).then((detectedTransport) => {
if (!detectedTransport) return;
activeTransport?.dispose();
activeTransport = detectedTransport;
});
};
/**
* Subscribes to react-refresh (fast refresh) updates by wrapping
* `scheduleRefresh` on every renderer injected into the React DevTools
* global hook. The react-refresh runtime calls `scheduleRefresh` after each
* hot update, so this works with any bundler that uses react-refresh (Vite,
* Next.js webpack, Next.js Turbopack, Metro) without bundler-specific code.
* Returns an unsubscribe function (a no-op in non-client environments like
* SSR, so callers never need an environment check). The returned function
* is also a `Disposable`, so it composes with other bippy subscriptions
* through `using`.
*
* The bundler's HMR transport is auto-detected and each refresh update is
* augmented with the hot-updated source file paths it reported.
*
* The handler runs after React has re-rendered with the new component
* types, so the refreshed root's fiber tree already carries them;
* `updatedFibers`/`staleFibers` are the mounted fibers matching the
* hot-swapped component types.
*
* @example
* ```ts
* const unsubscribe = instrumentReactRefresh({
* onRefresh(update) {
* for (const fiber of update.updatedFibers) {
* console.log("hot updated:", getDisplayName(fiber.type));
* }
* console.log("changed files:", update.filePaths);
* },
* });
* unsubscribe();
* ```
*
* Pair with `getSource(fiber)` from `bippy/source` to symbolicate the
* source locations of `updatedFibers` when needed.
*/
export const instrumentReactRefresh = (
options: ReactRefreshInstrumentationOptions,
): Unsubscribe => {
const { onRefresh } = options;
if (!onRefresh || !isClientEnvironment()) return toUnsubscribe(() => {});
ensureRefreshWired();
if (refreshHandlers.size === 0) {
detectTransportForNewSubscriber();
}
refreshHandlers.add(onRefresh);
return toUnsubscribe(() => {
refreshHandlers.delete(onRefresh);
});
};

View File

@@ -0,0 +1,188 @@
import { HMR_RECONNECT_DELAY_MS } from "./constants.js";
import { HmrTransport, HmrUpdateHandler } from "./types.js";
declare global {
var __turboModuleProxy: ((moduleName: string) => unknown) | undefined;
var nativeModuleProxy: Record<string, unknown> | undefined;
}
const getScriptUrlFromSourceCodeModule = (sourceCodeModule: unknown): string | null => {
if (typeof sourceCodeModule !== "object" || sourceCodeModule === null) return null;
if (!("getConstants" in sourceCodeModule)) return null;
const getConstants = sourceCodeModule.getConstants;
if (typeof getConstants !== "function") return null;
let constants: unknown;
try {
constants = getConstants.call(sourceCodeModule);
} catch {
return null;
}
if (typeof constants !== "object" || constants === null) return null;
if (!("scriptURL" in constants)) return null;
const scriptUrl = constants.scriptURL;
return typeof scriptUrl === "string" ? scriptUrl : null;
};
/**
* Resolves the URL the running React Native bundle was loaded from, using
* the same `SourceCode` native module React Native's own dev tooling reads
* (via the TurboModule proxy globals, so react-native is not imported).
* Returns `null` outside a Metro-served React Native runtime.
*
* @example
* ```ts
* getMetroBundleUrl();
* // "http://localhost:8081/index.bundle?platform=ios&dev=true"
* ```
*/
export const getMetroBundleUrl = (): string | null => {
if (typeof globalThis.__turboModuleProxy === "function") {
let sourceCodeModule: unknown;
try {
sourceCodeModule = globalThis.__turboModuleProxy("SourceCode");
} catch {
sourceCodeModule = null;
}
const scriptUrl = getScriptUrlFromSourceCodeModule(sourceCodeModule);
if (scriptUrl) return scriptUrl;
}
const legacySourceCodeModule = globalThis.nativeModuleProxy?.SourceCode;
return getScriptUrlFromSourceCodeModule(legacySourceCodeModule);
};
// HACK: module sourceURLs may be JSC-safe URLs where "//&" stands in for
// "?" (iOS 16.4 stack traces strip query strings), so the query separator
// must be normalized before URL parsing.
const normalizeJscSafeUrl = (jscSafeUrl: string): string => jscSafeUrl.replace("//&", "?");
const getSourcePathFromSourceUrl = (sourceUrl: string): string | null => {
let parsedUrl: URL;
try {
parsedUrl = new URL(normalizeJscSafeUrl(sourceUrl));
} catch {
return null;
}
let sourcePath = decodeURIComponent(parsedUrl.pathname);
if (sourcePath.startsWith("/")) sourcePath = sourcePath.slice(1);
// Metro rewrites each module's real extension to ".bundle" when building
// hot-update sourceURLs, so the original extension is unrecoverable.
if (sourcePath.endsWith(".bundle")) sourcePath = sourcePath.slice(0, -".bundle".length);
return sourcePath.length > 0 ? sourcePath : null;
};
const collectModuleSourcePaths = (hmrModules: unknown, filePaths: string[]) => {
if (!Array.isArray(hmrModules)) return;
for (const hmrModule of hmrModules) {
if (typeof hmrModule !== "object" || hmrModule === null) continue;
if (!("sourceURL" in hmrModule) || typeof hmrModule.sourceURL !== "string") continue;
const sourcePath = getSourcePathFromSourceUrl(hmrModule.sourceURL);
if (!sourcePath || sourcePath.includes("node_modules")) continue;
filePaths.push(sourcePath);
}
};
/**
* Extracts the updated source file paths from a raw Metro HMR WebSocket
* message. Paths are project-relative but extension-less (`src/app`, not
* `src/app.tsx`) because Metro rewrites module extensions to `.bundle`.
* The initial update replayed on connect is skipped. Returns an empty
* array for any other message shape.
*
* @example
* ```ts
* parseMetroUpdatePaths(rawMessageData);
* // ["src/app"]
* ```
*/
export const parseMetroUpdatePaths = (rawMessageData: string): string[] => {
let message: unknown;
try {
message = JSON.parse(rawMessageData);
} catch {
return [];
}
if (typeof message !== "object" || message === null) return [];
if (!("type" in message) || message.type !== "update") return [];
if (!("body" in message) || typeof message.body !== "object" || message.body === null) return [];
const updateBody = message.body;
if ("isInitialUpdate" in updateBody && updateBody.isInitialUpdate === true) return [];
const filePaths: string[] = [];
if ("added" in updateBody) collectModuleSourcePaths(updateBody.added, filePaths);
if ("modified" in updateBody) collectModuleSourcePaths(updateBody.modified, filePaths);
return filePaths;
};
export interface MetroHmrTransportOptions {
bundleUrl?: string;
}
/**
* Subscribes to the Metro dev server's `/hot` HMR WebSocket (as a second
* client alongside React Native's own) and invokes `onHmrUpdate` with the
* updated file paths on every hot update. Reconnects automatically when
* the dev server restarts. Returns `null` when no Metro bundle URL can be
* resolved (production builds, non-Metro runtimes).
*
* @example
* ```ts
* const transport = createMetroHmrTransport((filePaths) => {
* console.log("hot updated:", filePaths);
* });
* transport?.dispose();
* ```
*/
export const createMetroHmrTransport = (
onHmrUpdate: HmrUpdateHandler,
options: MetroHmrTransportOptions = {},
): HmrTransport | null => {
if (typeof WebSocket === "undefined") return null;
const bundleUrl = options.bundleUrl ?? getMetroBundleUrl();
if (!bundleUrl) return null;
let hotSocketUrl: string;
try {
const parsedBundleUrl = new URL(bundleUrl);
const socketProtocol = parsedBundleUrl.protocol === "https:" ? "wss" : "ws";
hotSocketUrl = `${socketProtocol}://${parsedBundleUrl.host}/hot`;
} catch {
return null;
}
let isDisposed = false;
let socket: WebSocket | null = null;
let reconnectTimerId: ReturnType<typeof setTimeout> | undefined;
const scheduleReconnect = () => {
if (isDisposed) return;
reconnectTimerId = setTimeout(connect, HMR_RECONNECT_DELAY_MS);
};
const connect = () => {
if (isDisposed) return;
const connectedSocket = new WebSocket(hotSocketUrl);
socket = connectedSocket;
connectedSocket.onopen = () => {
connectedSocket.send(
JSON.stringify({ type: "register-entrypoints", entryPoints: [bundleUrl] }),
);
};
connectedSocket.onmessage = (event) => {
const filePaths = parseMetroUpdatePaths(String(event.data));
if (filePaths.length > 0) onHmrUpdate(filePaths);
};
connectedSocket.onclose = scheduleReconnect;
};
connect();
return {
dispose: () => {
isDisposed = true;
clearTimeout(reconnectTimerId);
if (socket) {
socket.onclose = null;
socket.close();
}
},
};
};

View File

@@ -0,0 +1,72 @@
import { HMR_SOURCE_FILE_EXTENSION_REGEX } from "./constants.js";
import { normalizeHmrFilePath } from "./normalize-hmr-file-path.js";
import { HmrTransport, HmrUpdateHandler } from "./types.js";
interface WebpackHotUpdateGlobal {
(chunkId: unknown, updatedModules: Record<string, unknown> | undefined, runtime: unknown): void;
}
declare global {
interface Window {
webpackHotUpdate_N_E?: WebpackHotUpdateGlobal;
}
}
/**
* Normalizes webpack hot-update module keys into project-relative source
* file paths, dropping node_modules entries and non-source keys (e.g.
* webpack runtime helpers).
*
* @example
* ```ts
* normalizeWebpackModulePaths(["(app-pages-browser)/./app/page.tsx"]);
* // ["app/page.tsx"]
* ```
*/
export const normalizeWebpackModulePaths = (moduleKeys: string[]): string[] => {
const filePaths: string[] = [];
for (const moduleKey of moduleKeys) {
if (moduleKey.includes("node_modules")) continue;
const filePath = normalizeHmrFilePath(moduleKey);
if (!HMR_SOURCE_FILE_EXTENSION_REGEX.test(filePath)) continue;
filePaths.push(filePath);
}
return filePaths;
};
/**
* Subscribes to Next.js webpack hot updates by wrapping the
* `webpackHotUpdate_N_E` global and invokes `onHmrUpdate` with the updated
* file paths. Returns `null` when the page is not a Next.js webpack dev
* build.
*
* @example
* ```ts
* const transport = createNextWebpackHmrTransport((filePaths) => {
* console.log("hot updated:", filePaths);
* });
* transport?.dispose();
* ```
*/
export const createNextWebpackHmrTransport = (
onHmrUpdate: HmrUpdateHandler,
): HmrTransport | null => {
if (typeof window === "undefined") return null;
const originalHotUpdate = window.webpackHotUpdate_N_E;
if (typeof originalHotUpdate !== "function") return null;
const wrappedHotUpdate: WebpackHotUpdateGlobal = (chunkId, updatedModules, runtime) => {
const filePaths = normalizeWebpackModulePaths(Object.keys(updatedModules ?? {}));
if (filePaths.length > 0) onHmrUpdate(filePaths);
originalHotUpdate(chunkId, updatedModules, runtime);
};
window.webpackHotUpdate_N_E = wrappedHotUpdate;
return {
dispose: () => {
if (window.webpackHotUpdate_N_E === wrappedHotUpdate) {
window.webpackHotUpdate_N_E = originalHotUpdate;
}
},
};
};

View File

@@ -0,0 +1,24 @@
import { normalizeFileName } from "../source/get-source.js";
import { BUNDLER_LAYER_PREFIX_REGEX } from "./constants.js";
/**
* Normalizes a bundler module key or HMR update path into a plain,
* project-relative file path. Strips URL schemes (via
* {@link normalizeFileName}), bundler layer prefixes like
* `(app-pages-browser)/`, and leading `./` segments.
*
* @example
* ```ts
* normalizeHmrFilePath("(app-pages-browser)/./app/page.tsx");
* // "app/page.tsx"
* ```
*/
export const normalizeHmrFilePath = (filePath: string): string => {
let normalizedFilePath = normalizeFileName(filePath);
normalizedFilePath = normalizedFilePath.replace(BUNDLER_LAYER_PREFIX_REGEX, "");
if (normalizedFilePath.startsWith("./")) {
normalizedFilePath = normalizedFilePath.slice(2);
}
return normalizedFilePath;
};

7
node_modules/bippy/src/react-refresh/types.ts generated vendored Normal file
View File

@@ -0,0 +1,7 @@
export interface HmrUpdateHandler {
(filePaths: string[]): void;
}
export interface HmrTransport {
dispose: () => void;
}

View File

@@ -0,0 +1,116 @@
import { HMR_RECONNECT_DELAY_MS, VITE_WS_TOKEN_REGEX } from "./constants.js";
import { HmrTransport, HmrUpdateHandler } from "./types.js";
/**
* Extracts the accepted file paths from a raw Vite HMR WebSocket message.
* Only `js-update` entries are kept (a `css-update` swaps a stylesheet link
* without re-running modules). Returns an empty array for any other message
* shape.
*
* @example
* ```ts
* parseViteUpdatePaths(rawMessageData);
* // ["/src/app.tsx"]
* ```
*/
export const parseViteUpdatePaths = (rawMessageData: string): string[] => {
let message: unknown;
try {
message = JSON.parse(rawMessageData);
} catch {
return [];
}
if (typeof message !== "object" || message === null) return [];
if (!("type" in message) || message.type !== "update") return [];
if (!("updates" in message) || !Array.isArray(message.updates)) return [];
const filePaths: string[] = [];
for (const update of message.updates) {
if (typeof update !== "object" || update === null) continue;
if (!("type" in update) || update.type !== "js-update") continue;
if (!("acceptedPath" in update) || typeof update.acceptedPath !== "string") continue;
filePaths.push(update.acceptedPath);
}
return filePaths;
};
// HACK: a standalone script is not a Vite module, so import.meta.hot is
// unavailable; open a second HMR WebSocket using the wsToken scraped from
// the dev server's own /@vite/client source.
const fetchViteWsToken = async (): Promise<string | null> => {
try {
const response = await fetch("/@vite/client");
if (!response.ok) return null;
const clientSource = await response.text();
return VITE_WS_TOKEN_REGEX.exec(clientSource)?.[1] ?? null;
} catch {
return null;
}
};
/**
* Subscribes to the current page's Vite dev server HMR WebSocket and invokes
* `onHmrUpdate` with the updated file paths on every hot update. Reconnects
* automatically when the dev server restarts. Resolves `null` when the page
* is not served by Vite.
*
* @example
* ```ts
* const transport = await createViteHmrTransport((filePaths) => {
* console.log("hot updated:", filePaths);
* });
* transport?.dispose();
* ```
*/
export const createViteHmrTransport = async (
onHmrUpdate: HmrUpdateHandler,
): Promise<HmrTransport | null> => {
if (typeof window === "undefined" || typeof WebSocket === "undefined") return null;
const initialWsToken = await fetchViteWsToken();
if (!initialWsToken) return null;
let isDisposed = false;
let socket: WebSocket | null = null;
let reconnectTimerId: number | undefined;
const scheduleReconnect = () => {
if (isDisposed) return;
reconnectTimerId = window.setTimeout(() => {
void fetchViteWsToken().then((freshWsToken) => {
if (isDisposed) return;
if (freshWsToken) {
connect(freshWsToken);
} else {
scheduleReconnect();
}
});
}, HMR_RECONNECT_DELAY_MS);
};
const connect = (wsToken: string) => {
if (isDisposed) return;
const socketProtocol = location.protocol === "https:" ? "wss" : "ws";
const connectedSocket = new WebSocket(
`${socketProtocol}://${location.host}/?token=${wsToken}`,
"vite-hmr",
);
socket = connectedSocket;
connectedSocket.onmessage = (event) => {
const filePaths = parseViteUpdatePaths(String(event.data));
if (filePaths.length > 0) onHmrUpdate(filePaths);
};
connectedSocket.onclose = scheduleReconnect;
};
connect(initialWsToken);
return {
dispose: () => {
isDisposed = true;
window.clearTimeout(reconnectTimerId);
if (socket) {
socket.onclose = null;
socket.close();
}
},
};
};

39
node_modules/bippy/src/source/constants.ts generated vendored Normal file
View File

@@ -0,0 +1,39 @@
export const SCHEME_REGEX = /^[a-zA-Z][a-zA-Z\d+\-.]*:/;
export const INTERNAL_SCHEME_PREFIXES = [
"rsc://",
"file:///",
"webpack-internal://",
"webpack://",
"node:",
"turbopack://",
"metro://",
"/app-pages-browser/",
"/(app-pages-browser)/",
] as const;
export const ABOUT_REACT_PREFIX = "about://React/";
export const SERVER_COMPONENT_URL_PREFIXES = ["rsc://", ABOUT_REACT_PREFIX] as const;
export const ANONYMOUS_FILE_PATTERNS = ["<anonymous>", "eval", ""] as const;
export const SOURCE_FILE_EXTENSION_REGEX = /\.(jsx|tsx|ts|js)$/;
export const BUNDLED_FILE_PATTERN_REGEX =
/(\.min|bundle|chunk|vendor|vendors|runtime|polyfill|polyfills)\.(js|mjs|cjs)$|(chunk|bundle|vendor|vendors|runtime|polyfill|polyfills|framework|app|main|index)[-_.][A-Za-z0-9_-]{4,}\.(js|mjs|cjs)$|[\da-f]{8,}\.(js|mjs|cjs)$|[-_.][\da-f]{20,}\.(js|mjs|cjs)$|\/dist\/|\/build\/|\/.next\/|\/out\/|\/node_modules\/|\.webpack\.|\.vite\.|\.turbopack\./i;
export const QUERY_PARAMETER_PATTERN_REGEX = /^\?[\w~.-]+(?:=[^&#]*)?(?:&[\w~.-]+(?:=[^&#]*)?)*$/;
export const SERVER_FRAME_MARKER = "(at Server)";
export const SERVER_ENV_PATTERN = /\(at [^)]+\)$/;
export const REACT_STACK_BOTTOM_FRAME_PATTERNS = [
"react_stack_bottom_frame",
"react-stack-bottom-frame",
] as const;
// the first frame of a _debugStack is the JSX factory itself (jsxDEV), never
// user code, matching what react's own captureOwnerStack pops
export const JSX_FACTORY_FRAME_COUNT = 1;

View File

@@ -0,0 +1,93 @@
import { Fiber } from "../types.js";
import { getDisplayName } from "../core.js";
import { getParentStack } from "./owner-stack.js";
import { getSourceFromSourceMap, getSourceMap } from "./symbolication.js";
import { StackFrame } from "./parse-stack.js";
const extractComponentNameFromSource = (
sourceContent: string,
lineNumber: number,
): string | null => {
const lines = sourceContent.split("\n");
const targetLineIndex = lineNumber - 1;
if (targetLineIndex < 0 || targetLineIndex >= lines.length) {
return null;
}
const startLine = Math.max(0, targetLineIndex - 5);
const endLine = Math.min(lines.length, targetLineIndex + 5);
const contextLines = lines.slice(startLine, endLine).join("\n");
const arrowFunctionPattern = /(?:^|export\s+)(?:const|let|var)\s+(\w+)\s*=/m;
const functionPattern = /(?:^|export\s+)function\s+(\w+)/m;
const classPattern = /(?:^|export\s+)class\s+(\w+)/m;
const arrowMatch = contextLines.match(arrowFunctionPattern);
if (arrowMatch?.[1]) {
return arrowMatch[1];
}
const functionMatch = contextLines.match(functionPattern);
if (functionMatch?.[1]) {
return functionMatch[1];
}
const classMatch = contextLines.match(classPattern);
if (classMatch?.[1]) {
return classMatch[1];
}
return null;
};
export const getDisplayNameFromSource = async (
fiber: Fiber,
cache = true,
fetchFn?: (url: string) => Promise<Response>,
): Promise<string | null> => {
const parentStackFrames = await getParentStack(fiber, cache, fetchFn);
const stackFrame = parentStackFrames.filter((innerFrame) => innerFrame.fileName)[0];
if (!stackFrame?.fileName) {
return getDisplayName(fiber.type);
}
const bundleSourceMap = await getSourceMap(stackFrame.fileName, cache, fetchFn);
if (!bundleSourceMap) {
return getDisplayName(fiber.type);
}
let source: StackFrame | null = null;
if (typeof stackFrame.lineNumber === "number" && typeof stackFrame.columnNumber === "number") {
source = getSourceFromSourceMap(
bundleSourceMap,
stackFrame.lineNumber,
stackFrame.columnNumber,
);
}
if (!source?.fileName || !source.lineNumber) {
return getDisplayName(fiber.type);
}
if (!bundleSourceMap.sourcesContent) {
return getDisplayName(fiber.type);
}
const sourceIndex = bundleSourceMap.sources.indexOf(source.fileName);
if (sourceIndex === -1 || !bundleSourceMap.sourcesContent[sourceIndex]) {
return getDisplayName(fiber.type);
}
const sourceContent = bundleSourceMap.sourcesContent[sourceIndex];
const extractedName = extractComponentNameFromSource(sourceContent, source.lineNumber);
if (extractedName) {
return extractedName;
}
return getDisplayName(fiber.type);
};

257
node_modules/bippy/src/source/get-source.ts generated vendored Normal file
View File

@@ -0,0 +1,257 @@
import { Fiber } from "../types.js";
import { FiberSource } from "./types.js";
import {
SCHEME_REGEX,
INTERNAL_SCHEME_PREFIXES,
ABOUT_REACT_PREFIX,
ANONYMOUS_FILE_PATTERNS,
SOURCE_FILE_EXTENSION_REGEX,
BUNDLED_FILE_PATTERN_REGEX,
QUERY_PARAMETER_PATTERN_REGEX,
} from "./constants.js";
import { getDefinitionFrameFromOwnedChild, getParentStack, hasDebugStack } from "./owner-stack.js";
import { parseDebugStack } from "./parse-debug-stack.js";
import { StackFrame } from "./parse-stack.js";
import { symbolicateStack } from "./symbolication.js";
export const hasDebugSource = (
fiber: Fiber,
): fiber is Fiber & {
_debugSource: NonNullable<Fiber["_debugSource"]>;
} => {
const debugSource = fiber._debugSource;
if (!debugSource) {
return false;
}
return (
typeof debugSource === "object" &&
debugSource !== null &&
"fileName" in debugSource &&
typeof debugSource.fileName === "string" &&
"lineNumber" in debugSource &&
typeof debugSource.lineNumber === "number"
);
};
const toFiberSource = (stackFrame: StackFrame): FiberSource | null =>
stackFrame.fileName
? {
fileName: stackFrame.fileName,
lineNumber: stackFrame.lineNumber,
columnNumber: stackFrame.columnNumber,
functionName: stackFrame.functionName,
}
: null;
// the fiber's own _debugStack (react 19) is captured at its JSX creation
// site, so its first user-space frame IS the usage site - no need to
// re-invoke the component like the throwing trick does
const getUsageFrameFromDebugStack = (fiber: Fiber): StackFrame | null => {
if (!hasDebugStack(fiber)) {
return null;
}
const { frames, isTrusted } = parseDebugStack(fiber._debugStack);
if (!isTrusted) {
return null;
}
for (const stackFrame of frames) {
if (stackFrame.fileName) {
return stackFrame;
}
}
return null;
};
/**
* Returns the source of where the component is used. Available only in dev, for composite {@link Fiber}s.
*
* Resolution order:
* 1. `_debugSource` (react <19, requires the JSX source babel transform)
* 2. the fiber's own `_debugStack` (react 19) - the exact JSX creation site
* 3. an owned child's `_debugStack` bottom frame (react 19) - a location
* inside the component's own body; works for components that the throwing
* trick cannot locate (no hooks, no props access)
* 4. the legacy owner-stack path (throwing trick re-invocation)
*
* @example
* ```ts
* function Parent() {
* const data = useData();
* return <Child name={data.name} />; // <-- captures THIS line
* }
*
* function Child({ name }) {
* return <div>{name}</div>;
* }
*
* const source = await getSource(fiber);
* console.log(source.fileName, source.lineNumber);
* ```
*/
export const getSource = async (
fiber: Fiber,
cache = true,
fetchFn?: (url: string) => Promise<Response>,
): Promise<FiberSource | null> => {
if (hasDebugSource(fiber)) {
const debugSource = fiber._debugSource;
return debugSource || null;
}
const debugStackFrame =
getUsageFrameFromDebugStack(fiber) ?? getDefinitionFrameFromOwnedChild(fiber);
if (debugStackFrame) {
const [symbolicatedFrame] = await symbolicateStack([debugStackFrame], cache, fetchFn);
const debugStackSource = toFiberSource(symbolicatedFrame);
if (debugStackSource) {
return debugStackSource;
}
}
const parentStackFrames = await getParentStack(fiber, cache, fetchFn);
for (const stackFrame of parentStackFrames) {
if (stackFrame.fileName) {
return toFiberSource(stackFrame);
}
}
return null;
};
const getPathSegmentCount = (path: string): number => path.split("/").filter(Boolean).length;
const getFirstPathSegment = (path: string): string | null => {
const segments = path.split("/").filter(Boolean);
return segments[0] ?? null;
};
const stripSingleBasePathPrefix = (path: string): string => {
const firstSlashIndex = path.indexOf("/", 1);
if (firstSlashIndex === -1) {
return path;
}
const basePath = path.slice(0, firstSlashIndex);
if (getPathSegmentCount(basePath) !== 1) {
return path;
}
const remainderPath = path.slice(firstSlashIndex);
if (!SOURCE_FILE_EXTENSION_REGEX.test(remainderPath)) {
return path;
}
if (getPathSegmentCount(remainderPath) < 2) {
return path;
}
const firstRemainderSegment = getFirstPathSegment(remainderPath);
if (!firstRemainderSegment) {
return path;
}
if (firstRemainderSegment.startsWith("@")) {
return path;
}
if (firstRemainderSegment.length > 4) {
return path;
}
return remainderPath;
};
export const normalizeFileName = (fileName: string): string => {
if (!fileName) {
return "";
}
if (ANONYMOUS_FILE_PATTERNS.some((pattern) => pattern === fileName)) {
return "";
}
let normalizedFileName = fileName;
const isHttpUrl =
normalizedFileName.startsWith("http://") || normalizedFileName.startsWith("https://");
if (isHttpUrl) {
try {
const parsedUrl = new URL(normalizedFileName);
normalizedFileName = parsedUrl.pathname;
} catch {}
}
if (isHttpUrl) {
normalizedFileName = stripSingleBasePathPrefix(normalizedFileName);
}
if (normalizedFileName.startsWith(ABOUT_REACT_PREFIX)) {
const remainder = normalizedFileName.slice(ABOUT_REACT_PREFIX.length);
const slashIndex = remainder.indexOf("/");
const colonIndex = remainder.indexOf(":");
if (slashIndex !== -1 && (colonIndex === -1 || slashIndex < colonIndex)) {
normalizedFileName = remainder.slice(slashIndex + 1);
} else {
normalizedFileName = remainder;
}
}
let didStripPrefix = true;
while (didStripPrefix) {
didStripPrefix = false;
for (const prefix of INTERNAL_SCHEME_PREFIXES) {
if (normalizedFileName.startsWith(prefix)) {
normalizedFileName = normalizedFileName.slice(prefix.length);
if (prefix === "file:///") {
normalizedFileName = `/${normalizedFileName.replace(/^\/+/, "")}`;
}
didStripPrefix = true;
break;
}
}
}
if (SCHEME_REGEX.test(normalizedFileName)) {
const schemeMatch = normalizedFileName.match(SCHEME_REGEX);
if (schemeMatch) {
normalizedFileName = normalizedFileName.slice(schemeMatch[0].length);
}
}
if (normalizedFileName.startsWith("//")) {
const firstPathSlashIndex = normalizedFileName.indexOf("/", 2);
normalizedFileName =
firstPathSlashIndex === -1 ? "" : normalizedFileName.slice(firstPathSlashIndex);
}
const queryParameterIndex = normalizedFileName.indexOf("?");
if (queryParameterIndex !== -1) {
const potentialQueryParameters = normalizedFileName.slice(queryParameterIndex);
if (QUERY_PARAMETER_PATTERN_REGEX.test(potentialQueryParameters)) {
normalizedFileName = normalizedFileName.slice(0, queryParameterIndex);
}
}
return normalizedFileName;
};
export const isSourceFile = (fileName: string): boolean => {
const normalizedFileName = normalizeFileName(fileName);
if (!normalizedFileName) {
return false;
}
if (!SOURCE_FILE_EXTENSION_REGEX.test(normalizedFileName)) {
return false;
}
if (BUNDLED_FILE_PATTERN_REGEX.test(normalizedFileName)) {
return false;
}
return true;
};

17
node_modules/bippy/src/source/index.ts generated vendored Normal file
View File

@@ -0,0 +1,17 @@
export { formatOwnerStack, getOwnerStack, getParentStack, hasDebugStack } from "./owner-stack.js";
export { getSource, isSourceFile, normalizeFileName } from "./get-source.js";
export {
getSourceFromSourceMap,
getSourceMap,
symbolicateStack,
type DecodedSourceMapSection,
type IndexSourceMap,
type RawSourceMap,
type SourceMap,
type StandardSourceMap,
} from "./symbolication.js";
export type { FiberSource } from "./types.js";
export { parseStack, type ParseOptions, type StackFrame } from "./parse-stack.js";
export { getDisplayNameFromSource } from "./get-display-name-from-source.js";
export { getFiberHooks, type HookSource, type HooksNode, type HooksTree } from "./inspect-hooks.js";
export { parseHookNames, type HookNames } from "./parse-hook-names.js";

882
node_modules/bippy/src/source/inspect-hooks.ts generated vendored Normal file
View File

@@ -0,0 +1,882 @@
import type { Fiber, ContextDependency, MemoizedState, ReactContext } from "../types.js";
import { parseStack, type StackFrame } from "./parse-stack.js";
import { getRDTHook, _renderers } from "../rdt-hook.js";
const REACT_CONTEXT_TYPE = Symbol.for("react.context");
const REACT_MEMO_CACHE_SENTINEL = Symbol.for("react.memo_cache_sentinel");
const FUNCTION_COMPONENT_TAG = 0;
const CONTEXT_PROVIDER_TAG = 10;
const FORWARD_REF_TAG = 11;
const SIMPLE_MEMO_COMPONENT_TAG = 15;
export interface HookSource {
lineNumber: number | null;
columnNumber: number | null;
fileName: string | null;
functionName: string | null;
}
export interface HooksNode {
id: number | null;
isStateEditable: boolean;
name: string;
value: unknown;
subHooks: HooksNode[];
hookSource: HookSource | null;
}
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface HooksTree extends Array<HooksNode> {}
interface HookLogEntry {
displayName: string | null;
primitive: string;
stackError: Error;
value: unknown;
dispatcherHookName: string;
}
interface DispatcherRefContainer {
H?: unknown;
current?: unknown;
[key: string]: unknown;
}
let hookLog: HookLogEntry[] = [];
let primitiveStackCache: Map<string, StackFrame[]> | null = null;
let currentFiber: Fiber | null = null;
let currentHook: MemoizedState | null = null;
let currentContextDependency: ContextDependency<unknown> | null = null;
let currentThenableIndex = 0;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let currentThenableState: any[] | null = null;
const SuspenseException: unknown = new Error(
"Suspense Exception: This is not a real error! It's an implementation detail of `use` to interrupt the current render.",
);
const parseErrorStack = (error: Error): StackFrame[] =>
parseStack(error.stack || "", { includeInElement: false });
const nextHook = (): MemoizedState | null => {
const hook = currentHook;
if (hook !== null) currentHook = hook.next;
return hook;
};
const readContext = <T>(context: ReactContext<T>): T => {
if (currentFiber === null) return context._currentValue;
if (currentContextDependency === null) {
throw new Error("Context reads do not line up with context dependencies.");
}
if (Object.prototype.hasOwnProperty.call(currentContextDependency, "memoizedValue")) {
const value = currentContextDependency.memoizedValue as T;
currentContextDependency = currentContextDependency.next;
return value;
}
return context._currentValue;
};
const getDispatcherRef = (): DispatcherRefContainer | null => {
const rdtHook = getRDTHook();
const allRenderers = [..._renderers, ...rdtHook.renderers.values()];
for (const renderer of allRenderers) {
const ref = renderer.currentDispatcherRef;
if (ref && typeof ref === "object") return ref as DispatcherRefContainer;
}
return null;
};
const getDispatcherFromRef = (ref: DispatcherRefContainer): unknown =>
"H" in ref ? ref.H : ref.current;
const setDispatcherOnRef = (ref: DispatcherRefContainer, dispatcher: unknown): void => {
if ("H" in ref) {
ref.H = dispatcher;
} else {
ref.current = dispatcher;
}
};
const pushHookLogEntry = (
primitive: string,
value: unknown,
dispatcherHookName: string,
displayName: string | null = null,
): void => {
hookLog.push({
displayName,
primitive,
stackError: new Error(),
value,
dispatcherHookName,
});
};
const dispatcherUse = (usable: unknown): unknown => {
if (usable !== null && typeof usable === "object") {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const asThenable = usable as any;
if (typeof asThenable.then === "function") {
const thenable =
currentThenableState !== null && currentThenableIndex < currentThenableState.length
? currentThenableState[currentThenableIndex++]
: asThenable;
switch (thenable.status) {
case "fulfilled": {
pushHookLogEntry("Promise", thenable.value, "Use");
return thenable.value;
}
case "rejected":
throw thenable.reason;
}
pushHookLogEntry("Unresolved", thenable, "Use");
throw SuspenseException;
}
if (asThenable.$$typeof === REACT_CONTEXT_TYPE && "_currentValue" in asThenable) {
const context: ReactContext<unknown> = asThenable;
const value = readContext(context);
pushHookLogEntry("Context (use)", value, "Use", context.displayName || "Context");
return value;
}
}
throw new Error("An unsupported type was passed to use(): " + String(usable));
};
const dispatcherUseContext = (context: ReactContext<unknown>): unknown => {
const value = readContext(context);
pushHookLogEntry("Context", value, "Context", context.displayName || null);
return value;
};
const dispatcherUseState = (initialState: unknown): [unknown, () => void] => {
const hook = nextHook();
const state =
hook !== null
? hook.memoizedState
: typeof initialState === "function"
? (initialState as () => unknown)()
: initialState;
pushHookLogEntry("State", state, "State");
return [state, () => {}];
};
const dispatcherUseReducer = (
_reducer: unknown,
initialArg: unknown,
init?: (arg: unknown) => unknown,
): [unknown, () => void] => {
const hook = nextHook();
const state =
hook !== null ? hook.memoizedState : init !== undefined ? init(initialArg) : initialArg;
pushHookLogEntry("Reducer", state, "Reducer");
return [state, () => {}];
};
const dispatcherUseRef = (initialValue: unknown): { current: unknown } => {
const hook = nextHook();
const ref = hook !== null ? hook.memoizedState : { current: initialValue };
pushHookLogEntry("Ref", (ref as { current: unknown }).current, "Ref");
return ref as { current: unknown };
};
const dispatcherUseCacheRefresh = (): (() => void) => {
const hook = nextHook();
pushHookLogEntry("CacheRefresh", hook !== null ? hook.memoizedState : () => {}, "CacheRefresh");
return () => {};
};
const dispatcherUseLayoutEffect = (create: () => void): void => {
nextHook();
pushHookLogEntry("LayoutEffect", create, "LayoutEffect");
};
const dispatcherUseInsertionEffect = (create: () => unknown): void => {
nextHook();
pushHookLogEntry("InsertionEffect", create, "InsertionEffect");
};
const dispatcherUseEffect = (create: () => void): void => {
nextHook();
pushHookLogEntry("Effect", create, "Effect");
};
const dispatcherUseImperativeHandle = (ref: unknown): void => {
nextHook();
let instance: unknown;
if (ref !== null && typeof ref === "object" && "current" in ref) {
instance = ref.current;
}
pushHookLogEntry("ImperativeHandle", instance, "ImperativeHandle");
};
const dispatcherUseDebugValue = (
value: unknown,
formatterFn?: (value: unknown) => unknown,
): void => {
pushHookLogEntry(
"DebugValue",
typeof formatterFn === "function" ? formatterFn(value) : value,
"DebugValue",
);
};
const dispatcherUseCallback = (callback: unknown): unknown => {
const hook = nextHook();
pushHookLogEntry(
"Callback",
hook !== null ? (hook.memoizedState as unknown[])[0] : callback,
"Callback",
);
return callback;
};
const dispatcherUseMemo = (nextCreate: () => unknown): unknown => {
const hook = nextHook();
const value = hook !== null ? (hook.memoizedState as unknown[])[0] : nextCreate();
pushHookLogEntry("Memo", value, "Memo");
return value;
};
const dispatcherUseSyncExternalStore = (
_subscribe: unknown,
getSnapshot: () => unknown,
): unknown => {
const hook = nextHook();
nextHook();
const value = hook !== null ? hook.memoizedState : getSnapshot();
pushHookLogEntry("SyncExternalStore", value, "SyncExternalStore");
return value;
};
const dispatcherUseTransition = (): [boolean, () => void] => {
const stateHook = nextHook();
nextHook();
const isPending = stateHook !== null ? (stateHook.memoizedState as boolean) : false;
pushHookLogEntry("Transition", isPending, "Transition");
return [isPending, () => {}];
};
const dispatcherUseDeferredValue = (value: unknown): unknown => {
const hook = nextHook();
const previousValue = hook !== null ? hook.memoizedState : value;
pushHookLogEntry("DeferredValue", previousValue, "DeferredValue");
return previousValue;
};
const dispatcherUseId = (): string => {
const hook = nextHook();
const identifier = hook !== null ? (hook.memoizedState as string) : "";
pushHookLogEntry("Id", identifier, "Id");
return identifier;
};
const dispatcherUseMemoCache = (size: number): unknown[] => {
const fiber = currentFiber;
if (fiber === null || fiber === undefined) return [];
const memoCache = (
fiber.updateQueue as { memoCache?: { data: unknown[][]; index: number } } | null
)?.memoCache;
if (memoCache === null || memoCache === undefined) return [];
let memoCacheSlots = memoCache.data[memoCache.index];
if (memoCacheSlots === undefined) {
memoCacheSlots = memoCache.data[memoCache.index] = Array.from(
{ length: size },
() => REACT_MEMO_CACHE_SENTINEL,
);
}
memoCache.index++;
return memoCacheSlots;
};
const dispatcherUseOptimistic = (passthrough: unknown): [unknown, () => void] => {
const hook = nextHook();
const state = hook !== null ? hook.memoizedState : passthrough;
pushHookLogEntry("Optimistic", state, "Optimistic");
return [state, () => {}];
};
const inspectActionStateHook = (
hook: MemoizedState | null,
initialState: unknown,
): { value: unknown; error: unknown } => {
let value: unknown;
let error: unknown = null;
if (hook !== null) {
const actionResult = hook.memoizedState;
if (
typeof actionResult === "object" &&
actionResult !== null &&
"then" in actionResult &&
typeof actionResult.then === "function"
) {
const thenable = actionResult as { status?: string; value?: unknown; reason?: unknown };
switch (thenable.status) {
case "fulfilled":
value = thenable.value;
break;
case "rejected":
error = thenable.reason;
break;
default:
error = SuspenseException;
value = thenable;
}
} else {
value = actionResult;
}
} else {
value = initialState;
}
return { value, error };
};
const createActionStateDispatcher =
(primitive: string) =>
(_action: unknown, initialState: unknown): [unknown, () => void, boolean] => {
const hook = nextHook();
nextHook();
nextHook();
const stackError = new Error();
const { value, error } = inspectActionStateHook(hook, initialState);
hookLog.push({
displayName: null,
primitive,
stackError,
value,
dispatcherHookName: primitive,
});
if (error !== null) throw error;
return [value, () => {}, false];
};
const dispatcherUseActionState = createActionStateDispatcher("ActionState");
const dispatcherUseFormState = createActionStateDispatcher("FormState");
const dispatcherUseHostTransitionStatus = (): unknown => {
// HACK: creating a minimal fake context because useHostTransitionStatus reads from an internal context not available outside React
const status = readContext({ _currentValue: null } as unknown as ReactContext<unknown>);
pushHookLogEntry("HostTransitionStatus", status, "HostTransitionStatus");
return status;
};
const dispatcherUseEffectEvent = (callback: (...args: unknown[]) => unknown): typeof callback => {
nextHook();
pushHookLogEntry("EffectEvent", callback, "EffectEvent");
return callback;
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const Dispatcher: Record<string, (...args: any[]) => any> = {
readContext,
use: dispatcherUse,
useCallback: dispatcherUseCallback,
useContext: dispatcherUseContext,
useEffect: dispatcherUseEffect,
useImperativeHandle: dispatcherUseImperativeHandle,
useLayoutEffect: dispatcherUseLayoutEffect,
useInsertionEffect: dispatcherUseInsertionEffect,
useMemo: dispatcherUseMemo,
useReducer: dispatcherUseReducer,
useRef: dispatcherUseRef,
useState: dispatcherUseState,
useDebugValue: dispatcherUseDebugValue,
useDeferredValue: dispatcherUseDeferredValue,
useTransition: dispatcherUseTransition,
useSyncExternalStore: dispatcherUseSyncExternalStore,
useId: dispatcherUseId,
useHostTransitionStatus: dispatcherUseHostTransitionStatus,
useFormState: dispatcherUseFormState,
useActionState: dispatcherUseActionState,
useOptimistic: dispatcherUseOptimistic,
useMemoCache: dispatcherUseMemoCache,
useCacheRefresh: dispatcherUseCacheRefresh,
useEffectEvent: dispatcherUseEffectEvent,
};
const DispatcherProxy =
typeof Proxy === "undefined"
? Dispatcher
: new Proxy(Dispatcher, {
get(target, prop: string) {
if (Object.prototype.hasOwnProperty.call(target, prop)) return target[prop];
const error = new Error("Missing method in Dispatcher: " + prop);
error.name = "ReactDebugToolsUnsupportedHookError";
throw error;
},
});
const getPrimitiveStackCache = (): Map<string, StackFrame[]> => {
if (primitiveStackCache !== null) return primitiveStackCache;
const cache = new Map<string, StackFrame[]>();
let capturedHookLog: HookLogEntry[];
try {
Dispatcher.useContext({ _currentValue: null });
Dispatcher.useState(null);
Dispatcher.useReducer((state: unknown) => state, null);
Dispatcher.useRef(null);
if (typeof Dispatcher.useCacheRefresh === "function") Dispatcher.useCacheRefresh();
Dispatcher.useLayoutEffect(() => {});
Dispatcher.useInsertionEffect(() => {});
Dispatcher.useEffect(() => {});
Dispatcher.useImperativeHandle(undefined, () => null);
Dispatcher.useDebugValue(null);
Dispatcher.useCallback(() => {});
Dispatcher.useTransition();
Dispatcher.useSyncExternalStore(
() => () => {},
() => null,
() => null,
);
Dispatcher.useDeferredValue(null);
Dispatcher.useMemo(() => null);
Dispatcher.useOptimistic(null, (state: unknown) => state);
Dispatcher.useFormState((state: unknown) => state, null);
Dispatcher.useActionState((state: unknown) => state, null);
Dispatcher.useHostTransitionStatus();
if (typeof Dispatcher.useMemoCache === "function") Dispatcher.useMemoCache(0);
if (typeof Dispatcher.use === "function") {
Dispatcher.use({ $$typeof: REACT_CONTEXT_TYPE, _currentValue: null });
Dispatcher.use({ then() {}, status: "fulfilled", value: null });
try {
Dispatcher.use({ then() {} });
} catch {
/* noop */
}
}
Dispatcher.useId();
if (typeof Dispatcher.useEffectEvent === "function") Dispatcher.useEffectEvent(() => {});
} finally {
capturedHookLog = hookLog;
hookLog = [];
}
for (const hook of capturedHookLog) {
cache.set(hook.primitive, parseErrorStack(hook.stackError));
}
primitiveStackCache = cache;
return primitiveStackCache;
};
let mostLikelyAncestorIndex = 0;
const findSharedIndex = (
hookStack: StackFrame[],
rootStack: StackFrame[],
rootIndex: number,
): number => {
// mostLikelyAncestorIndex is cached across inspections, so it can exceed the
// bounds of a later, shorter root stack (e.g. truncated Error.stackTraceLimit)
if (rootIndex >= rootStack.length) return -1;
const source = rootStack[rootIndex].source;
hookSearch: for (let hookIndex = 0; hookIndex < hookStack.length; hookIndex++) {
if (hookStack[hookIndex].source === source) {
for (
let rootOffset = rootIndex + 1, hookOffset = hookIndex + 1;
rootOffset < rootStack.length && hookOffset < hookStack.length;
rootOffset++, hookOffset++
) {
if (hookStack[hookOffset].source !== rootStack[rootOffset].source) continue hookSearch;
}
return hookIndex;
}
}
return -1;
};
const findCommonAncestorIndex = (rootStack: StackFrame[], hookStack: StackFrame[]): number => {
let rootIndex = findSharedIndex(hookStack, rootStack, mostLikelyAncestorIndex);
if (rootIndex !== -1) return rootIndex;
for (
let candidateIndex = 0;
candidateIndex < rootStack.length && candidateIndex < 5;
candidateIndex++
) {
rootIndex = findSharedIndex(hookStack, rootStack, candidateIndex);
if (rootIndex !== -1) {
mostLikelyAncestorIndex = candidateIndex;
return rootIndex;
}
}
return -1;
};
const parseHookName = (functionName: string | undefined): string => {
if (!functionName) return "";
let startIndex = functionName.lastIndexOf("[as ");
if (startIndex !== -1) {
return parseHookName(functionName.slice(startIndex + "[as ".length, -1));
}
startIndex = functionName.lastIndexOf(".");
startIndex = startIndex === -1 ? 0 : startIndex + 1;
if (functionName.slice(startIndex).startsWith("unstable_")) startIndex += "unstable_".length;
if (functionName.slice(startIndex).startsWith("experimental_"))
startIndex += "experimental_".length;
if (functionName.slice(startIndex, startIndex + 3) === "use") {
if (functionName.length - startIndex === 3) return "Use";
startIndex += 3;
}
return functionName.slice(startIndex);
};
const isReactWrapper = (functionName: string | undefined, wrapperName: string): boolean => {
const hookName = parseHookName(functionName);
if (wrapperName === "HostTransitionStatus") {
return hookName === wrapperName || hookName === "FormStatus";
}
return hookName === wrapperName;
};
const findPrimitiveIndex = (hookStack: StackFrame[], hook: HookLogEntry): number => {
const stackCache = getPrimitiveStackCache();
const primitiveStack = stackCache.get(hook.primitive);
if (primitiveStack === undefined) return -1;
for (
let frameIndex = 0;
frameIndex < primitiveStack.length && frameIndex < hookStack.length;
frameIndex++
) {
if (primitiveStack[frameIndex].source !== hookStack[frameIndex].source) {
if (
frameIndex < hookStack.length - 1 &&
isReactWrapper(hookStack[frameIndex].functionName, hook.dispatcherHookName)
) {
frameIndex++;
}
if (
frameIndex < hookStack.length - 1 &&
isReactWrapper(hookStack[frameIndex].functionName, hook.dispatcherHookName)
) {
frameIndex++;
}
return frameIndex;
}
}
return -1;
};
const parseTrimmedStack = (
rootStack: StackFrame[],
hook: HookLogEntry,
): [StackFrame | null, StackFrame[] | null] => {
const hookStack = parseErrorStack(hook.stackError);
const rootIndex = findCommonAncestorIndex(rootStack, hookStack);
const primitiveIndex = findPrimitiveIndex(hookStack, hook);
if (rootIndex === -1 || primitiveIndex === -1 || rootIndex - primitiveIndex < 2) {
if (primitiveIndex === -1) return [null, null];
return [hookStack[primitiveIndex - 1] ?? null, null];
}
return [hookStack[primitiveIndex - 1] ?? null, hookStack.slice(primitiveIndex, rootIndex - 1)];
};
const NON_ID_HOOK_PRIMITIVES = new Set([
"Context",
"Context (use)",
"DebugValue",
"Promise",
"Unresolved",
"HostTransitionStatus",
]);
const buildTree = (rootStack: StackFrame[], capturedHookLog: HookLogEntry[]): HooksTree => {
const rootChildren: HooksNode[] = [];
let previousStack: StackFrame[] | null = null;
let levelChildren = rootChildren;
let nativeHookID = 0;
const childrenStack: HooksNode[][] = [];
for (const hook of capturedHookLog) {
const [primitiveFrame, stack] = parseTrimmedStack(rootStack, hook);
let displayName = hook.displayName;
if (displayName === null && primitiveFrame !== null) {
displayName =
parseHookName(primitiveFrame.functionName) || parseHookName(hook.dispatcherHookName);
}
if (stack !== null) {
let commonSteps = 0;
if (previousStack !== null) {
while (commonSteps < stack.length && commonSteps < previousStack.length) {
const stackSource = stack[stack.length - commonSteps - 1].source;
const previousSource = previousStack[previousStack.length - commonSteps - 1].source;
if (stackSource !== previousSource) break;
commonSteps++;
}
for (let popIndex = previousStack.length - 1; popIndex > commonSteps; popIndex--) {
levelChildren = childrenStack.pop() ?? rootChildren;
}
}
for (let stackIndex = stack.length - commonSteps - 1; stackIndex >= 1; stackIndex--) {
const children: HooksNode[] = [];
const stackFrame = stack[stackIndex];
const levelChild: HooksNode = {
id: null,
isStateEditable: false,
name: parseHookName(stack[stackIndex - 1].functionName),
value: undefined,
subHooks: children,
hookSource: {
lineNumber: stackFrame.lineNumber ?? null,
columnNumber: stackFrame.columnNumber ?? null,
functionName: stackFrame.functionName ?? null,
fileName: stackFrame.fileName ?? null,
},
};
levelChildren.push(levelChild);
childrenStack.push(levelChildren);
levelChildren = children;
}
previousStack = stack;
}
const { primitive } = hook;
const id = NON_ID_HOOK_PRIMITIVES.has(primitive) ? null : nativeHookID++;
const isStateEditable = primitive === "Reducer" || primitive === "State";
const name = displayName || primitive;
const firstStackFrame = stack?.[0];
const hookSource: HookSource = {
lineNumber: firstStackFrame?.lineNumber ?? null,
columnNumber: firstStackFrame?.columnNumber ?? null,
functionName: firstStackFrame?.functionName ?? null,
fileName: firstStackFrame?.fileName ?? null,
};
levelChildren.push({ id, isStateEditable, name, value: hook.value, subHooks: [], hookSource });
}
processDebugValues(rootChildren, null);
return rootChildren;
};
const processDebugValues = (hooksTree: HooksTree, parentHooksNode: HooksNode | null): void => {
const debugValueNodes: HooksNode[] = [];
for (let nodeIndex = 0; nodeIndex < hooksTree.length; nodeIndex++) {
const hooksNode = hooksTree[nodeIndex];
if (hooksNode.name === "DebugValue" && hooksNode.subHooks.length === 0) {
hooksTree.splice(nodeIndex, 1);
nodeIndex--;
debugValueNodes.push(hooksNode);
} else {
processDebugValues(hooksNode.subHooks, hooksNode);
}
}
if (parentHooksNode !== null) {
if (debugValueNodes.length === 1) {
parentHooksNode.value = debugValueNodes[0].value;
} else if (debugValueNodes.length > 1) {
parentHooksNode.value = debugValueNodes.map(({ value }) => value);
}
}
};
const setupContexts = (contextMap: Map<ReactContext<unknown>, unknown>, fiber: Fiber): void => {
let current: Fiber | null = fiber;
while (current) {
if (current.tag === CONTEXT_PROVIDER_TAG) {
let context = current.type as ReactContext<unknown>;
if ("_context" in context && context._context !== undefined) {
context = context._context as ReactContext<unknown>;
}
if (!contextMap.has(context)) {
contextMap.set(context, context._currentValue);
context._currentValue = (current.memoizedProps as { value: unknown }).value;
}
}
current = current.return;
}
};
const restoreContexts = (contextMap: Map<ReactContext<unknown>, unknown>): void => {
contextMap.forEach((value, context) => {
context._currentValue = value;
});
};
const handleRenderFunctionError = (error: unknown): void => {
if (error === SuspenseException) return;
if (error instanceof Error && error.name === "ReactDebugToolsUnsupportedHookError") throw error;
const wrapperError = new Error("Error rendering inspected component", { cause: error });
wrapperError.name = "ReactDebugToolsRenderError";
(wrapperError as { cause: unknown }).cause = error;
throw wrapperError;
};
const resolveDefaultProps = (
Component: unknown,
baseProps: Record<string, unknown>,
): Record<string, unknown> => {
if (
Component &&
typeof Component === "object" &&
"defaultProps" in Component &&
Component.defaultProps
) {
const props = { ...baseProps };
const defaultProps = Component.defaultProps as Record<string, unknown>;
for (const propName in defaultProps) {
if (props[propName] === undefined) {
props[propName] = defaultProps[propName];
}
}
return props;
}
return baseProps;
};
const suppressConsole = (): Record<string, unknown> => {
const originalMethods: Record<string, unknown> = {};
for (const method in console) {
try {
originalMethods[method] = (console as Record<string, unknown>)[method];
(console as Record<string, unknown>)[method] = () => {};
} catch {
/* noop */
}
}
return originalMethods;
};
const restoreConsole = (originalMethods: Record<string, unknown>): void => {
for (const method in originalMethods) {
try {
(console as Record<string, unknown>)[method] = originalMethods[method];
} catch {
/* noop */
}
}
};
const performDispatcherInspection = (
dispatcherRef: DispatcherRefContainer,
renderFn: () => void,
): HooksTree => {
const previousDispatcher = getDispatcherFromRef(dispatcherRef);
setDispatcherOnRef(dispatcherRef, DispatcherProxy);
let capturedHookLog: HookLogEntry[] = [];
let ancestorStackError: Error | undefined;
try {
ancestorStackError = new Error();
renderFn();
} catch (renderError) {
handleRenderFunctionError(renderError);
} finally {
capturedHookLog = hookLog;
hookLog = [];
setDispatcherOnRef(dispatcherRef, previousDispatcher);
}
const rootStack = ancestorStackError !== undefined ? parseErrorStack(ancestorStackError) : [];
return buildTree(rootStack, capturedHookLog);
};
const requireDispatcherRef = (): DispatcherRefContainer => {
const dispatcherRef = getDispatcherRef();
if (!dispatcherRef) {
throw new Error(
"No React renderer found. Make sure React is loaded and bippy's hook is installed.",
);
}
return dispatcherRef;
};
const resolveContextDependency = (fiber: Fiber): void => {
if (Object.prototype.hasOwnProperty.call(fiber, "dependencies")) {
const dependencies = fiber.dependencies;
currentContextDependency = dependencies !== null ? dependencies.firstContext : null;
} else if (Object.prototype.hasOwnProperty.call(fiber, "dependencies_old")) {
const dependencies = (fiber as unknown as { dependencies_old: typeof fiber.dependencies })
.dependencies_old;
currentContextDependency = dependencies !== null ? dependencies!.firstContext : null;
} else if (Object.prototype.hasOwnProperty.call(fiber, "dependencies_new")) {
const dependencies = (fiber as unknown as { dependencies_new: typeof fiber.dependencies })
.dependencies_new;
currentContextDependency = dependencies !== null ? dependencies!.firstContext : null;
} else if (Object.prototype.hasOwnProperty.call(fiber, "contextDependencies")) {
const contextDependencies = (
fiber as unknown as {
contextDependencies: { first: ContextDependency<unknown> | null } | null;
}
).contextDependencies;
currentContextDependency = contextDependencies !== null ? contextDependencies.first : null;
} else {
throw new Error("Unsupported React version.");
}
};
export const getFiberHooks = (fiber: Fiber): HooksTree => {
const dispatcherRef = requireDispatcherRef();
if (
fiber.tag !== FUNCTION_COMPONENT_TAG &&
fiber.tag !== SIMPLE_MEMO_COMPONENT_TAG &&
fiber.tag !== FORWARD_REF_TAG
) {
throw new Error("Unknown Fiber. Needs to be a function component to inspect hooks.");
}
getPrimitiveStackCache();
currentHook = fiber.memoizedState;
currentFiber = fiber;
const debugThenableState =
fiber.dependencies &&
(fiber.dependencies as { _debugThenableState?: { thenables?: unknown[] } })._debugThenableState;
const usedThenables = debugThenableState
? debugThenableState.thenables || debugThenableState
: null;
currentThenableState = Array.isArray(usedThenables) ? usedThenables : null;
currentThenableIndex = 0;
resolveContextDependency(fiber);
const type = fiber.type;
let props = fiber.memoizedProps as Record<string, unknown>;
if (type !== fiber.elementType) {
props = resolveDefaultProps(type, props);
}
const originalConsoleMethods = suppressConsole();
const contextMap = new Map<ReactContext<unknown>, unknown>();
try {
if (
currentContextDependency !== null &&
!Object.prototype.hasOwnProperty.call(currentContextDependency, "memoizedValue")
) {
setupContexts(contextMap, fiber);
}
if (fiber.tag === FORWARD_REF_TAG) {
return performDispatcherInspection(dispatcherRef, () => {
(type as { render: (props: Record<string, unknown>, ref: unknown) => unknown }).render(
props,
fiber.ref,
);
});
}
return performDispatcherInspection(dispatcherRef, () => {
(type as (props: Record<string, unknown>) => unknown)(props);
});
} finally {
currentFiber = null;
currentHook = null;
currentContextDependency = null;
currentThenableState = null;
currentThenableIndex = 0;
restoreContexts(contextMap);
restoreConsole(originalConsoleMethods);
}
};

725
node_modules/bippy/src/source/owner-stack.ts generated vendored Normal file
View File

@@ -0,0 +1,725 @@
import {
_renderers,
ActivityComponentTag,
ClassComponentTag,
Fiber,
ForwardRefTag,
FunctionComponentTag,
getRDTHook,
HostComponentTag,
HostHoistableTag,
HostSingletonTag,
LazyComponentTag,
SimpleMemoComponentTag,
SuspenseComponentTag,
SuspenseListComponentTag,
ViewTransitionComponentTag,
getDisplayName,
traverseFiber,
} from "../core.js";
import { ServerComponentInfo } from "../types.js";
import {
SERVER_FRAME_MARKER,
SERVER_ENV_PATTERN,
SERVER_COMPONENT_URL_PREFIXES,
} from "./constants.js";
import { parseDebugStack } from "./parse-debug-stack.js";
import { parseStack, StackFrame } from "./parse-stack.js";
import { symbolicateStack } from "./symbolication.js";
export const hasDebugStack = (
fiber: Fiber,
): fiber is Fiber & {
_debugStack: NonNullable<Fiber["_debugStack"]>;
} => {
return fiber._debugStack instanceof Error && typeof fiber._debugStack?.stack === "string";
};
const isFiberOwner = (owner: Fiber | ServerComponentInfo): owner is Fiber =>
typeof (owner as Fiber).tag === "number";
// react's typings (and bippy's Fiber, which mirrors them) declare _debugOwner
// as a Fiber, but react 19 flight sets a ReactComponentInfo object for server
// component owners
const getDebugOwner = (fiber: Fiber): Fiber | ServerComponentInfo | undefined =>
fiber._debugOwner as Fiber | ServerComponentInfo | undefined;
/**
* Locates a frame inside the fiber's own function body without invoking it:
* any child fiber owned by this fiber was created by JSX inside its body, so
* the bottom user-space frame of that child's _debugStack sits in this
* component. The enclosing line/column (V8 CallSite API) points at the
* function definition start. Requires React 19 (_debugStack).
*/
export const getDefinitionFrameFromOwnedChild = (fiber: Fiber): StackFrame | null => {
let ownedChildDebugStack: Error | null = null;
traverseFiber(fiber, (childFiber) => {
if (childFiber === fiber) {
return false;
}
const childOwner = childFiber._debugOwner;
if (
(childOwner === fiber || (fiber.alternate !== null && childOwner === fiber.alternate)) &&
childFiber._debugStack instanceof Error
) {
ownedChildDebugStack = childFiber._debugStack;
return true;
}
return false;
});
if (!ownedChildDebugStack) {
return null;
}
const { frames, isTrusted } = parseDebugStack(ownedChildDebugStack);
if (!isTrusted) {
return null;
}
for (let frameIndex = frames.length - 1; frameIndex >= 0; frameIndex--) {
const stackFrame = frames[frameIndex];
if (!stackFrame.fileName) {
continue;
}
return {
...stackFrame,
lineNumber: stackFrame.enclosingLineNumber || stackFrame.lineNumber,
columnNumber: stackFrame.enclosingColumnNumber || stackFrame.columnNumber,
};
}
return null;
};
const getCurrentDispatcher = (): null | React.RefObject<unknown> => {
const rdtHook = getRDTHook();
for (const renderer of [...Array.from(_renderers), ...Array.from(rdtHook.renderers.values())]) {
const currentDispatcherRef = renderer.currentDispatcherRef;
if (currentDispatcherRef && typeof currentDispatcherRef === "object") {
return "H" in currentDispatcherRef ? currentDispatcherRef.H : currentDispatcherRef.current;
}
}
return null;
};
const setCurrentDispatcher = (value: null | React.RefObject<unknown>): void => {
for (const renderer of _renderers) {
const currentDispatcherRef = renderer.currentDispatcherRef;
if (currentDispatcherRef && typeof currentDispatcherRef === "object") {
if ("H" in currentDispatcherRef) {
currentDispatcherRef.H = value;
} else {
currentDispatcherRef.current = value;
}
}
}
};
const describeBuiltInComponentFrame = (name: string): string => {
return `\n in ${name}`;
};
export const describeDebugInfoFrame = (name: string, env?: string): string => {
let frameDescription = describeBuiltInComponentFrame(name);
if (env) {
frameDescription += ` (at ${env})`;
}
return frameDescription;
};
let reEntry = false;
// Computing a frame throws and parses two full error stacks, so cache per
// component type like React DevTools does.
const componentFrameCache = new WeakMap<React.ComponentType<unknown>, string>();
// https://github.com/facebook/react/blob/f739642745577a8e4dcb9753836ac3589b9c590a/packages/react-devtools-shared/src/backend/shared/DevToolsComponentStackFrame.js#L22
const describeNativeComponentFrame = (
component: React.ComponentType<unknown>,
construct: boolean,
): string => {
if (!component || reEntry) {
return "";
}
const cachedFrame = componentFrameCache.get(component);
if (cachedFrame !== undefined) {
return cachedFrame;
}
const previousPrepareStackTrace = Error.prepareStackTrace;
// HACK: V8 API allows undefined but bun-types declares it as non-optional
(Error as { prepareStackTrace?: typeof Error.prepareStackTrace }).prepareStackTrace = undefined;
reEntry = true;
const previousDispatcher = getCurrentDispatcher();
setCurrentDispatcher(null);
const previousConsoleError = console.error;
const previousConsoleWarn = console.warn;
console.error = () => {};
console.warn = () => {};
try {
/**
* Finding a common stack frame between sample and control errors can be
* tricky given the different types and levels of stack trace truncation from
* different JS VMs. So instead we'll attempt to control what that common
* frame should be through this object method:
* Having both the sample and control errors be in the function under the
* `DescribeNativeComponentFrameRoot` property, + setting the `name` and
* `displayName` properties of the function ensures that a stack
* frame exists that has the method name `DescribeNativeComponentFrameRoot` in
* it for both control and sample stacks.
*/
const RunInRootFrame = {
DetermineComponentFrameRoot() {
let control: unknown;
try {
// This should throw.
if (construct) {
// Something should be setting the props in the constructor.
const ThrowingConstructor = function () {
throw Error();
};
Object.defineProperty(ThrowingConstructor.prototype, "props", {
set: function () {
// We use a throwing setter instead of frozen or non-writable props
// because that won't throw in a non-strict mode function.
throw Error();
},
});
if (typeof Reflect === "object" && Reflect.construct) {
// We construct a different control for this case to include any extra
// frames added by the construct call.
try {
Reflect.construct(ThrowingConstructor, []);
} catch (caughtError) {
control = caughtError;
}
Reflect.construct(component, [], ThrowingConstructor);
} else {
try {
// @ts-expect-error -- ThrowingConstructor is a constructor function
ThrowingConstructor.call();
} catch (caughtError) {
control = caughtError;
}
// @ts-expect-error -- ThrowingConstructor is a constructor function
component.call(ThrowingConstructor.prototype);
}
} else {
try {
throw Error();
} catch (caughtError) {
control = caughtError;
}
// TODO(luna): This will currently only throw if the function component
// tries to access React/ReactDOM/props. We should probably make this throw
// in simple components too
const maybePromise = (component as () => Promise<unknown>)();
// If the function component returns a promise, it's likely an async
// component, which we don't yet support. Attach a noop catch handler to
// silence the error.
// TODO: Implement component stacks for async client components?
// eslint-disable-next-line @typescript-eslint/no-misused-promises -- we literally check if this is a promise here
if (maybePromise && typeof maybePromise.catch === "function") {
maybePromise.catch(() => {});
}
}
} catch (sample: unknown) {
// This is inlined manually because closure doesn't do it for us.
if (
sample instanceof Error &&
control instanceof Error &&
typeof sample.stack === "string"
) {
return [sample.stack, control.stack];
}
}
return [null, null];
},
};
// @ts-expect-error --- displayName is not a property of the function
RunInRootFrame.DetermineComponentFrameRoot.displayName = "DetermineComponentFrameRoot";
const namePropDescriptor = Object.getOwnPropertyDescriptor(
// eslint-disable-next-line @typescript-eslint/unbound-method
RunInRootFrame.DetermineComponentFrameRoot,
"name",
);
// Before ES6, the `name` property was not configurable.
if (namePropDescriptor?.configurable) {
// V8 utilizes a function's `name` property when generating a stack trace.
Object.defineProperty(
// eslint-disable-next-line @typescript-eslint/unbound-method
RunInRootFrame.DetermineComponentFrameRoot,
// Configurable properties can be updated even if its writable descriptor
// is set to `false`.
"name",
{ value: "DetermineComponentFrameRoot" },
);
}
const [sampleStack, controlStack] = RunInRootFrame.DetermineComponentFrameRoot();
if (sampleStack && controlStack) {
// This extracts the first frame from the sample that isn't also in the control.
// Skipping one frame that we assume is the frame that calls the two.
const sampleLines = sampleStack.split("\n");
const controlLines = controlStack.split("\n");
let sampleIndex = 0;
let controlIndex = 0;
while (
sampleIndex < sampleLines.length &&
!sampleLines[sampleIndex].includes("DetermineComponentFrameRoot")
) {
sampleIndex++;
}
while (
controlIndex < controlLines.length &&
!controlLines[controlIndex].includes("DetermineComponentFrameRoot")
) {
controlIndex++;
}
// We couldn't find our intentionally injected common root frame, attempt
// to find another common root frame by search from the bottom of the
// control stack...
if (sampleIndex === sampleLines.length || controlIndex === controlLines.length) {
sampleIndex = sampleLines.length - 1;
controlIndex = controlLines.length - 1;
while (
sampleIndex >= 1 &&
controlIndex >= 0 &&
sampleLines[sampleIndex] !== controlLines[controlIndex]
) {
// We expect at least one stack frame to be shared.
// Typically this will be the root most one. However, stack frames may be
// cut off due to maximum stack limits. In this case, one maybe cut off
// earlier than the other. We assume that the sample is longer or the same
// and there for cut off earlier. So we should find the root most frame in
// the sample somewhere in the control.
controlIndex--;
}
}
for (; sampleIndex >= 1 && controlIndex >= 0; sampleIndex--, controlIndex--) {
// Next we find the first one that isn't the same which should be the
// frame that called our sample function and the control.
if (sampleLines[sampleIndex] !== controlLines[controlIndex]) {
// In V8, the first line is describing the message but other VMs don't.
// If we're about to return the first line, and the control is also on the same
// line, that's a pretty good indicator that our sample threw at same line as
// the control. I.e. before we entered the sample frame. So we ignore this result.
// This can happen if you passed a class to function component, or non-function.
if (sampleIndex !== 1 || controlIndex !== 1) {
do {
sampleIndex--;
controlIndex--;
// We may still have similar intermediate frames from the construct call.
// The next one that isn't the same should be our match though.
if (controlIndex < 0 || sampleLines[sampleIndex] !== controlLines[controlIndex]) {
// V8 adds a "new" prefix for native classes. Let's remove it to make it prettier.
let stackFrame = `\n${sampleLines[sampleIndex].replace(" at new ", " at ")}`;
const displayName = getDisplayName(component);
// If our component frame is labeled "<anonymous>"
// but we have a user-provided "displayName"
// splice it in to make the stack more readable.
if (displayName && stackFrame.includes("<anonymous>")) {
stackFrame = stackFrame.replace("<anonymous>", displayName);
}
// Return the line we found.
componentFrameCache.set(component, stackFrame);
return stackFrame;
}
} while (sampleIndex >= 1 && controlIndex >= 0);
}
break;
}
}
}
} finally {
reEntry = false;
Error.prepareStackTrace = previousPrepareStackTrace;
setCurrentDispatcher(previousDispatcher);
console.error = previousConsoleError;
console.warn = previousConsoleWarn;
}
const componentName = component ? getDisplayName(component) : "";
const syntheticFrame = componentName ? describeBuiltInComponentFrame(componentName) : "";
componentFrameCache.set(component, syntheticFrame);
return syntheticFrame;
};
// https://github.com/facebook/react/blob/ac3e705a18696168acfcaed39dce0cfaa6be8836/packages/react-reconciler/src/ReactFiberComponentStack.js#L180
export const describeFiber = (fiber: Fiber, childFiber: Fiber | null): string => {
const tag = fiber.tag as number;
let stackFrame = "";
switch (tag) {
case ActivityComponentTag:
stackFrame = describeBuiltInComponentFrame("Activity");
break;
case ClassComponentTag:
stackFrame = describeNativeComponentFrame(fiber.type, true);
break;
case ForwardRefTag:
stackFrame = describeNativeComponentFrame(
(fiber.type as { render: React.ComponentType<unknown> }).render,
false,
);
break;
case FunctionComponentTag:
case SimpleMemoComponentTag:
stackFrame = describeNativeComponentFrame(fiber.type, false);
break;
case HostComponentTag:
case HostHoistableTag:
case HostSingletonTag:
stackFrame = describeBuiltInComponentFrame(fiber.type as string);
break;
case LazyComponentTag:
// TODO: When we support Thenables as component types we should rename this.
stackFrame = describeBuiltInComponentFrame("Lazy");
break;
case SuspenseComponentTag:
if (fiber.child !== childFiber && childFiber !== null) {
// If we came from the second Fiber then we're in the Suspense Fallback.
stackFrame = describeBuiltInComponentFrame("Suspense Fallback");
} else {
stackFrame = describeBuiltInComponentFrame("Suspense");
}
break;
case SuspenseListComponentTag:
stackFrame = describeBuiltInComponentFrame("SuspenseList");
break;
case ViewTransitionComponentTag:
// Note: enableViewTransition feature flag is not available in this codebase,
// so we'll always include ViewTransition
stackFrame = describeBuiltInComponentFrame("ViewTransition");
break;
default:
return "";
}
return stackFrame;
};
/**
* Builds a component-stack string by walking the fiber `return` chain, the
* pre-react-19 substitute for `_debugStack` (which is why the frame locations
* come from re-invocation in {@link describeFiber} rather than a real stack).
*/
export const getFallbackParentStack = (thisFiber: Fiber): string => {
try {
let componentStack = "";
let currentFiber: Fiber | null = thisFiber;
let previousFiber: Fiber | null = null;
do {
componentStack += describeFiber(currentFiber, previousFiber);
// Add any Server Component stack frames in reverse order (dev only).
// Since we don't have __DEV__ in this codebase, we'll check for _debugInfo
const debugInfo = currentFiber._debugInfo;
if (debugInfo && Array.isArray(debugInfo)) {
for (let i = debugInfo.length - 1; i >= 0; i--) {
const debugEntry = debugInfo[i];
if (typeof debugEntry.name === "string") {
componentStack += describeDebugInfoFrame(debugEntry.name, debugEntry.env);
}
}
}
previousFiber = currentFiber;
currentFiber = currentFiber.return;
} while (currentFiber);
return componentStack;
} catch (error) {
if (error instanceof Error) {
return `\nError generating stack: ${error.message}\n${error.stack}`;
}
return "";
}
};
/**
* takes Error.stack and formats it to only the React owner stack
*
* before:
* ```
* Error: react-stack-top-frame
* at fakeJSXCallSite (http://localhost:3000/_next/static/chunks/<chunk-name>._.js:17665:16)
* at TodoItem (rsc://React/Server/file:///path/to/project/.next/server/chunks/ssr/<chunk-name>._.js)
* at react-stack-bottom-frame (http://localhost:3000/_next/static/chunks/<chunk-name>._.js:17984:89)
* ```
*
* after:
* ```
* at TodoItem (rsc://React/Server/file:///path/to/project/.next/server/chunks/ssr/<chunk-name>._.js)
* ```
*
* @see https://github.com/facebook/react/blob/main/packages/react-devtools-shared/src/backend/shared/DevToolsOwnerStack.js#L12
*/
export const formatOwnerStack = (stack: string): string => {
const prevPrepareStackTrace = Error.prepareStackTrace;
// HACK: V8 API allows undefined but bun-types declares it as non-optional
(Error as { prepareStackTrace?: typeof Error.prepareStackTrace }).prepareStackTrace = undefined;
let formattedStack = stack;
if (!formattedStack) {
return "";
}
Error.prepareStackTrace = prevPrepareStackTrace;
if (formattedStack.startsWith("Error: react-stack-top-frame\n")) {
// V8's default formatting prefixes with the error message which we
// don't want/need
formattedStack = formattedStack.slice(29);
}
const firstNewlineIndex = formattedStack.indexOf("\n");
if (firstNewlineIndex !== -1) {
// pop the JSX frame
formattedStack = formattedStack.slice(firstNewlineIndex + 1);
}
let bottomFrameIndex = Math.max(
formattedStack.indexOf("react_stack_bottom_frame"),
formattedStack.indexOf("react-stack-bottom-frame"),
);
if (bottomFrameIndex !== -1) {
bottomFrameIndex = formattedStack.lastIndexOf("\n", bottomFrameIndex);
}
if (bottomFrameIndex !== -1) {
// cut off everything after the bottom frame since it'll be internals.
formattedStack = formattedStack.slice(0, bottomFrameIndex);
} else {
// we didn't find any internal callsite out to user space.
// This means that this was called outside an owner or the owner is fully internal.
// to keep things light we exclude the entire trace in this case.
return "";
}
return formattedStack;
};
interface DebugStackEntry {
componentName: string;
stackFrames: StackFrame[];
}
const isReactServerComponentFrame = (stackFrame: StackFrame): boolean =>
Boolean(
stackFrame.functionName && stackFrame.fileName && isServerComponentUrl(stackFrame.fileName),
);
const areStackFramesEqual = (firstFrame: StackFrame, secondFrame: StackFrame): boolean =>
firstFrame.fileName === secondFrame.fileName &&
firstFrame.lineNumber === secondFrame.lineNumber &&
firstFrame.columnNumber === secondFrame.columnNumber;
const buildFunctionNameToRscFramesMap = (
debugStackEntries: DebugStackEntry[],
): Map<string, StackFrame[]> => {
const functionNameToRscFrames = new Map<string, StackFrame[]>();
for (const debugStackEntry of debugStackEntries) {
for (const stackFrame of debugStackEntry.stackFrames) {
if (!isReactServerComponentFrame(stackFrame)) continue;
const functionName = stackFrame.functionName!;
const framesForFunction = functionNameToRscFrames.get(functionName) ?? [];
const isDuplicateFrame = framesForFunction.some((existingFrame) =>
areStackFramesEqual(existingFrame, stackFrame),
);
if (!isDuplicateFrame) {
framesForFunction.push(stackFrame);
functionNameToRscFrames.set(functionName, framesForFunction);
}
}
}
return functionNameToRscFrames;
};
const getEnrichedServerStackFrame = (
serverFrame: StackFrame,
functionNameToRscFrames: Map<string, StackFrame[]>,
functionNameToUsageIndex: Map<string, number>,
): StackFrame => {
if (!serverFrame.functionName) {
return { ...serverFrame, isServer: true };
}
const availableRscFrames = functionNameToRscFrames.get(serverFrame.functionName);
if (!availableRscFrames || availableRscFrames.length === 0) {
return { ...serverFrame, isServer: true };
}
const currentUsageIndex = functionNameToUsageIndex.get(serverFrame.functionName) ?? 0;
const resolvedRscFrame = availableRscFrames[currentUsageIndex % availableRscFrames.length];
functionNameToUsageIndex.set(serverFrame.functionName, currentUsageIndex + 1);
return {
...serverFrame,
isServer: true,
fileName: resolvedRscFrame.fileName,
lineNumber: resolvedRscFrame.lineNumber,
columnNumber: resolvedRscFrame.columnNumber,
source: serverFrame.source?.replace(
SERVER_FRAME_MARKER,
`(${resolvedRscFrame.fileName}:${resolvedRscFrame.lineNumber}:${resolvedRscFrame.columnNumber})`,
),
};
};
const isServerComponentUrl = (url: string): boolean =>
SERVER_COMPONENT_URL_PREFIXES.some((prefix) => url.startsWith(prefix));
// flight installs fake server frames (rsc:// or about://React/ urls) into
// client-side debug stacks, so server detection must be per-frame
const markFlightServerFrame = (stackFrame: StackFrame): StackFrame =>
!stackFrame.isServer && stackFrame.fileName && isServerComponentUrl(stackFrame.fileName)
? { ...stackFrame, isServer: true }
: stackFrame;
/**
* Builds owner-chain stack frames from the _debugStack errors React 19
* attaches at JSX creation, walking `_debugOwner` across both client fibers
* and server components (ReactComponentInfo, which chains via `.owner` and
* carries `.debugStack`). This is exact - no re-invoking components, no
* name-matching heuristics - but requires React 19.
*/
const getOwnerStackFromDebugStacks = (fiber: Fiber): StackFrame[] => {
const ownerStackFrames: StackFrame[] = [];
let owner: Fiber | ServerComponentInfo | null | undefined = fiber;
while (owner) {
if (isFiberOwner(owner)) {
const ownerFiber: Fiber = owner;
owner = getDebugOwner(ownerFiber);
if (owner && hasDebugStack(ownerFiber)) {
const { frames, isTrusted } = parseDebugStack(ownerFiber._debugStack);
if (isTrusted) {
for (const stackFrame of frames) {
ownerStackFrames.push(markFlightServerFrame(stackFrame));
}
}
}
} else {
const serverOwner: ServerComponentInfo = owner;
owner = serverOwner.owner;
// server stacks are captured and pre-trimmed by flight, so they carry
// no bottom-frame sentinel and are trusted as-is
if (owner && serverOwner.debugStack instanceof Error) {
for (const serverFrame of parseDebugStack(serverOwner.debugStack).frames) {
ownerStackFrames.push({ ...serverFrame, isServer: true });
}
}
}
}
return ownerStackFrames;
};
const getDebugStackEntries = (rootFiber: Fiber): DebugStackEntry[] => {
const debugStackEntries: DebugStackEntry[] = [];
traverseFiber(
rootFiber,
(currentFiber) => {
if (!hasDebugStack(currentFiber)) return;
const componentName =
typeof currentFiber.type !== "string"
? getDisplayName(currentFiber.type) || "<anonymous>"
: currentFiber.type;
debugStackEntries.push({
componentName,
stackFrames: parseStack(formatOwnerStack(currentFiber._debugStack?.stack)),
});
},
true,
);
return debugStackEntries;
};
/**
* Returns a stack of ALL ancestor components in the render tree (the fiber's
* `return` chain), including wrappers that render `{children}` without having
* created this fiber's JSX. Locations come from re-invoking each component
* with a throwing dispatcher; server frames are enriched from debug stacks by
* name matching. Works on every React version.
*/
export const getParentStack = async (
fiber: Fiber,
shouldCache = true,
fetchFunction?: (url: string) => Promise<Response>,
): Promise<StackFrame[]> => {
const debugStackEntries = getDebugStackEntries(fiber);
const fallbackStackFrames = parseStack(getFallbackParentStack(fiber));
const functionNameToRscFrames = buildFunctionNameToRscFramesMap(debugStackEntries);
const functionNameToUsageIndex = new Map<string, number>();
const enrichedStackFrames = fallbackStackFrames.map((stackFrame): StackFrame => {
const isServerFrame =
(stackFrame.source?.includes(SERVER_FRAME_MARKER) ?? false) ||
(stackFrame.source != null && SERVER_ENV_PATTERN.test(stackFrame.source));
if (isServerFrame) {
return getEnrichedServerStackFrame(
stackFrame,
functionNameToRscFrames,
functionNameToUsageIndex,
);
}
return stackFrame;
});
const deduplicatedStackFrames = enrichedStackFrames.filter((stackFrame, index, frames) => {
if (index === 0) return true;
const previousFrame = frames[index - 1];
return stackFrame.functionName !== previousFrame.functionName;
});
return symbolicateStack(deduplicatedStackFrames, shouldCache, fetchFunction);
};
// an owner frame is only actionable if it can point an editor somewhere:
// it needs a file location and must not be ignore-listed bundler/framework code
const isLocatableFrame = (stackFrame: StackFrame): boolean =>
Boolean(stackFrame.fileName) && !stackFrame.isIgnoreListed;
/**
* Returns the stack of components that CREATED this fiber's JSX (the
* `_debugOwner` chain), with exact creation-site locations from React 19's
* `_debugStack` errors - including server component owners. Wrappers that
* merely render `{children}` do not appear; use {@link getParentStack} for
* the full render-tree ancestry. Falls back to {@link getParentStack} on
* React <19, when no trusted debug stacks exist, or when the owner chain
* yields no locatable frames (so callers always get the most useful stack
* available).
*/
export const getOwnerStack = async (
fiber: Fiber,
shouldCache = true,
fetchFunction?: (url: string) => Promise<Response>,
): Promise<StackFrame[]> => {
const debugStackFrames = getOwnerStackFromDebugStacks(fiber);
if (debugStackFrames.length > 0) {
// the owner chain does not include the fiber itself, but bippy's stacks
// always start with the fiber's own frame
const selfFrame: StackFrame = getDefinitionFrameFromOwnedChild(fiber) ?? {};
selfFrame.functionName = getDisplayName(fiber.type) ?? selfFrame.functionName;
const symbolicatedFrames = await symbolicateStack(
[selfFrame, ...debugStackFrames],
shouldCache,
fetchFunction,
);
const hasLocatableOwnerFrame = symbolicatedFrames.some(
(stackFrame, frameIndex) => frameIndex > 0 && isLocatableFrame(stackFrame),
);
if (hasLocatableOwnerFrame) {
return symbolicatedFrames;
}
}
return getParentStack(fiber, shouldCache, fetchFunction);
};

133
node_modules/bippy/src/source/parse-debug-stack.ts generated vendored Normal file
View File

@@ -0,0 +1,133 @@
import { JSX_FACTORY_FRAME_COUNT, REACT_STACK_BOTTOM_FRAME_PATTERNS } from "./constants.js";
import { parseStack, StackFrame } from "./parse-stack.js";
interface V8CallSite {
getFunctionName?: () => string | null;
getScriptNameOrSourceURL?: () => string | null;
getLineNumber?: () => number | null;
getColumnNumber?: () => number | null;
getEnclosingLineNumber?: () => number | null;
getEnclosingColumnNumber?: () => number | null;
getTypeName?: () => string | null;
getMethodName?: () => string | null;
getEvalOrigin?: () => string | null;
isNative?: () => boolean;
isEval?: () => boolean;
toString: () => string;
}
export interface ParsedDebugStack {
frames: StackFrame[];
// React appends a react-stack-bottom-frame sentinel to stacks captured
// during render; without it the JSX was created outside a render and the
// lower frames are arbitrary bootstrapping code
isTrusted: boolean;
}
const parsedDebugStackCache = new WeakMap<Error, ParsedDebugStack>();
const isReactBottomFrameName = (functionName: string): boolean =>
REACT_STACK_BOTTOM_FRAME_PATTERNS.some((pattern) => functionName.includes(pattern));
const getCallSiteFunctionName = (callSite: V8CallSite): string => {
const functionName = callSite.getFunctionName?.() ?? "";
if (functionName) {
return functionName;
}
const typeName = callSite.getTypeName?.() ?? "";
const methodName = callSite.getMethodName?.() ?? "";
if (typeName && methodName) {
return `${typeName}.${methodName}`;
}
return methodName;
};
const collectStructuredFrames = (callSites: V8CallSite[]): ParsedDebugStack => {
const frames: StackFrame[] = [];
for (
let callSiteIndex = JSX_FACTORY_FRAME_COUNT;
callSiteIndex < callSites.length;
callSiteIndex++
) {
const callSite = callSites[callSiteIndex];
const functionName = getCallSiteFunctionName(callSite);
if (isReactBottomFrameName(functionName)) {
return { frames, isTrusted: true };
}
if (callSite.isNative?.()) {
frames.push({ functionName: functionName || undefined });
continue;
}
let fileName = callSite.getScriptNameOrSourceURL?.() ?? "";
if (!fileName && callSite.isEval?.()) {
fileName = callSite.getEvalOrigin?.() ?? "";
}
frames.push({
functionName: functionName && functionName !== "<anonymous>" ? functionName : undefined,
fileName: fileName && fileName !== "<anonymous>" ? fileName : undefined,
lineNumber: callSite.getLineNumber?.() ?? undefined,
columnNumber: callSite.getColumnNumber?.() ?? undefined,
enclosingLineNumber: callSite.getEnclosingLineNumber?.() ?? undefined,
enclosingColumnNumber: callSite.getEnclosingColumnNumber?.() ?? undefined,
source: ` at ${callSite.toString()}`,
});
}
return { frames, isTrusted: false };
};
const parseMaterializedStack = (stackString: string): ParsedDebugStack => {
let bottomFrameIndex = -1;
for (const pattern of REACT_STACK_BOTTOM_FRAME_PATTERNS) {
bottomFrameIndex = stackString.indexOf(pattern);
if (bottomFrameIndex !== -1) break;
}
const trimmedStack =
bottomFrameIndex === -1
? stackString
: stackString.slice(0, stackString.lastIndexOf("\n", bottomFrameIndex));
return {
frames: parseStack(trimmedStack).slice(JSX_FACTORY_FRAME_COUNT),
isTrusted: bottomFrameIndex !== -1,
};
};
/**
* Parses a React `_debugStack` Error, preferring V8's structured CallSite API
* (via Error.prepareStackTrace) over string parsing. Structured frames carry
* enclosing line/column - the function definition start, not the call site -
* and are immune to source-mapped `.stack` strings. Falls back to string
* parsing on engines without CallSites (JSC, SpiderMonkey) or when the stack
* was already materialized. The leading JSX factory frame (jsxDEV) and
* everything at or below React's bottom-frame sentinel are dropped.
*/
export const parseDebugStack = (debugStack: Error): ParsedDebugStack => {
const cachedResult = parsedDebugStackCache.get(debugStack);
if (cachedResult) {
return cachedResult;
}
let structuredResult: ParsedDebugStack | null = null;
const collectFramesAndFormatStack = (error: Error, callSites: V8CallSite[]): string => {
structuredResult = collectStructuredFrames(callSites);
// this return value becomes error.stack permanently, so emit the default
// V8 format for any later reader of the same error
let stackString = `${error.name || "Error"}: ${error.message || ""}`;
for (const callSite of callSites) {
stackString += `\n at ${callSite.toString()}`;
}
return stackString;
};
const previousPrepareStackTrace = Error.prepareStackTrace;
// node's CallSite typings disagree with browser-safe optional methods
Error.prepareStackTrace = collectFramesAndFormatStack as typeof Error.prepareStackTrace;
let stackString: string;
try {
stackString = String(debugStack.stack);
} finally {
Error.prepareStackTrace = previousPrepareStackTrace;
}
const result = structuredResult ?? parseMaterializedStack(stackString);
parsedDebugStackCache.set(debugStack, result);
return result;
};

224
node_modules/bippy/src/source/parse-hook-names.ts generated vendored Normal file
View File

@@ -0,0 +1,224 @@
import type { HooksNode, HooksTree, HookSource } from "./inspect-hooks.js";
import { getSourceMap, getSourceFromSourceMap, type SourceMap } from "./symbolication.js";
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface HookNames extends Map<string, string> {}
const UNNAMED_HOOKS = new Set([
"Effect",
"LayoutEffect",
"InsertionEffect",
"ImperativeHandle",
"DebugValue",
]);
// HACK: matches `const/let/var [name, ...] = use...(...` or `const/let/var name = use...(...`
// across up to 10 lines; handles TypeScript generics like `useState<T>(`
const HOOK_DECLARATION_REGEX =
/(?:const|let|var)\s+((?:\[[\s\S]*?\]|\w+))\s*=\s*(?:[\w$.]+\.)*use[A-Z]\w*\s*(?:<[\s\S]*?>)?\s*\(/g;
export const getHookSourceLocationKey = (hookSource: HookSource): string =>
`${hookSource.fileName ?? ""}:${hookSource.lineNumber ?? 0}:${hookSource.columnNumber ?? 0}`;
const flattenHooksTree = (hooksTree: HooksTree): HooksNode[] => {
const hooksList: HooksNode[] = [];
const collectNamedHooks = (tree: HooksTree): void => {
for (const hook of tree) {
if (UNNAMED_HOOKS.has(hook.name)) continue;
hooksList.push(hook);
if (hook.subHooks.length > 0) collectNamedHooks(hook.subHooks);
}
};
collectNamedHooks(hooksTree);
return hooksList;
};
const findSourceContentByFileName = (
sources: string[],
sourcesContent: string[] | undefined,
fileName: string,
): string | null => {
if (!sourcesContent) return null;
const sourceIndex = sources.indexOf(fileName);
return sourceIndex !== -1 ? (sourcesContent[sourceIndex] ?? null) : null;
};
const getSourceContentFromSourceMap = (
sourceMap: SourceMap,
originalFileName: string,
): string | null => {
const directResult = findSourceContentByFileName(
sourceMap.sources,
sourceMap.sourcesContent,
originalFileName,
);
if (directResult) return directResult;
if (sourceMap.sections) {
for (const section of sourceMap.sections) {
const sectionResult = findSourceContentByFileName(
section.map.sources,
section.map.sourcesContent,
originalFileName,
);
if (sectionResult) return sectionResult;
}
}
return null;
};
const extractVariableNameFromBinding = (binding: string): string | null => {
const trimmed = binding.trim();
if (trimmed.startsWith("[")) {
const match = trimmed.match(/\[\s*(\w+)/);
return match ? match[1] : null;
}
return /^\w+$/.test(trimmed) ? trimmed : null;
};
export const extractHookVariableName = (
sourceCode: string,
lineNumber: number,
columnNumber: number,
): string | null => {
const lines = sourceCode.split("\n");
const hookLineIndex = lineNumber - 1;
if (hookLineIndex < 0 || hookLineIndex >= lines.length) return null;
const searchStartLine = Math.max(0, hookLineIndex - 10);
const chunkLines = lines.slice(searchStartLine, hookLineIndex + 1);
const sourceChunk = chunkLines.join("\n");
const allMatches = [...sourceChunk.matchAll(HOOK_DECLARATION_REGEX)];
const hookPositionInChunk = sourceChunk.lastIndexOf("\n") + 1 + columnNumber;
const closestMatch = allMatches.filter((match) => match.index! <= hookPositionInChunk).at(-1);
if (closestMatch) {
return extractVariableNameFromBinding(closestMatch[1]);
}
return null;
};
interface ResolvedSource {
sourceCode: string;
lineNumber: number;
columnNumber: number;
}
interface SourceResolutionContext {
sourceMapsByFile: Map<string, SourceMap | null>;
sourceContentCache: Map<string, string | null>;
fetchFn?: (url: string) => Promise<Response>;
}
const resolveOriginalSource = async (
runtimeFileName: string,
runtimeLine: number,
runtimeColumn: number,
context: SourceResolutionContext,
): Promise<ResolvedSource | null> => {
const { sourceMapsByFile, sourceContentCache, fetchFn } = context;
if (!sourceMapsByFile.has(runtimeFileName)) {
sourceMapsByFile.set(runtimeFileName, await getSourceMap(runtimeFileName, true, fetchFn));
}
const sourceMap = sourceMapsByFile.get(runtimeFileName) ?? null;
if (sourceMap) {
const originalLocation = getSourceFromSourceMap(sourceMap, runtimeLine, runtimeColumn);
if (originalLocation?.fileName && originalLocation.lineNumber !== undefined) {
const cacheKey = `sourcemap:${runtimeFileName}:${originalLocation.fileName}`;
if (!sourceContentCache.has(cacheKey)) {
sourceContentCache.set(
cacheKey,
getSourceContentFromSourceMap(sourceMap, originalLocation.fileName),
);
}
const originalSourceCode = sourceContentCache.get(cacheKey) ?? null;
if (originalSourceCode) {
return {
sourceCode: originalSourceCode,
lineNumber: originalLocation.lineNumber,
columnNumber: originalLocation.columnNumber ?? 0,
};
}
}
}
if (!sourceContentCache.has(runtimeFileName)) {
try {
const fetchImpl = fetchFn ?? fetch;
const response = await fetchImpl(runtimeFileName);
sourceContentCache.set(runtimeFileName, response.ok ? await response.text() : null);
} catch {
sourceContentCache.set(runtimeFileName, null);
}
}
const runtimeSourceCode = sourceContentCache.get(runtimeFileName) ?? null;
if (runtimeSourceCode) {
return {
sourceCode: runtimeSourceCode,
lineNumber: runtimeLine,
columnNumber: runtimeColumn,
};
}
return null;
};
export const parseHookNames = async (
hooksTree: HooksTree,
fetchFn?: (url: string) => Promise<Response>,
): Promise<HookNames> => {
const hookNames: HookNames = new Map();
const hooksList = flattenHooksTree(hooksTree);
if (hooksList.length === 0) return hookNames;
const resolutionContext: SourceResolutionContext = {
sourceMapsByFile: new Map(),
sourceContentCache: new Map(),
fetchFn,
};
await Promise.all(
hooksList.map(async (hook) => {
const hookSource = hook.hookSource;
if (
!hookSource ||
!hookSource.fileName ||
hookSource.lineNumber === null ||
hookSource.columnNumber === null
) {
return;
}
const resolved = await resolveOriginalSource(
hookSource.fileName,
hookSource.lineNumber,
hookSource.columnNumber,
resolutionContext,
);
if (!resolved) return;
const variableName = extractHookVariableName(
resolved.sourceCode,
resolved.lineNumber,
resolved.columnNumber,
);
if (variableName) {
const locationKey = getHookSourceLocationKey(hookSource);
hookNames.set(locationKey, variableName);
}
}),
);
return hookNames;
};

150
node_modules/bippy/src/source/parse-stack.ts generated vendored Normal file
View File

@@ -0,0 +1,150 @@
export interface StackFrame {
args?: unknown[];
columnNumber?: number;
lineNumber?: number;
// start of the enclosing function (the definition, not the call site);
// only available from V8's structured CallSite API
enclosingLineNumber?: number;
enclosingColumnNumber?: number;
fileName?: string;
functionName?: string;
source?: string;
isServer?: boolean;
isSymbolicated?: boolean;
// the source map ignore-listed this frame's original source (x_google_ignoreList)
isIgnoreListed?: boolean;
}
export interface ParseOptions {
slice?: number | [number, number];
allowEmpty?: boolean;
includeInElement?: boolean;
}
const FIREFOX_SAFARI_STACK_REGEXP = /(^|@)\S+:\d+/;
const CHROME_IE_STACK_REGEXP = /^\s*at .*(\S+:\d+|\(native\))/m;
const SAFARI_NATIVE_CODE_REGEXP = /^(eval@)?(\[native code\])?$/;
export const parseStack = (stackString: string, options?: ParseOptions): StackFrame[] => {
if (options?.includeInElement !== false) {
const lines = stackString.split("\n");
const frames: StackFrame[] = [];
for (const rawLine of lines) {
if (/^\s*at\s+/.test(rawLine)) {
const parsed = parseV8OrIeString(rawLine, undefined)[0];
if (parsed) frames.push(parsed);
} else if (/^\s*in\s+/.test(rawLine)) {
const elementName = rawLine.replace(/^\s*in\s+/, "").replace(/\s*\(at .*\)$/, "");
frames.push({ functionName: elementName, source: rawLine });
} else if (rawLine.match(FIREFOX_SAFARI_STACK_REGEXP)) {
const parsed = parseFFOrSafariString(rawLine, undefined)[0];
if (parsed) frames.push(parsed);
}
}
return applySlice(frames, options);
}
if (stackString.match(CHROME_IE_STACK_REGEXP)) {
return parseV8OrIeString(stackString, options);
}
return parseFFOrSafariString(stackString, options);
};
export const extractLocation = (
urlLike: string,
): [string, string | undefined, string | undefined] => {
if (!urlLike.includes(":")) return [urlLike, undefined, undefined];
// HACK: Chrome/V8 stack traces wrap location in parens: "(file.js:10:5)"
// We need to strip these outer parens but preserve parens in paths (e.g., Next.js route groups like "(docs)")
// Chrome format always ends with `:col)` where digit comes right before the closing paren
const isWrappedLocation = urlLike.startsWith("(") && /:\d+\)$/.test(urlLike);
const sanitizedResult = isWrappedLocation ? urlLike.slice(1, -1) : urlLike;
const regExp = /(.+?)(?::(\d+))?(?::(\d+))?$/;
const parts = regExp.exec(sanitizedResult);
if (!parts) return [sanitizedResult, undefined, undefined];
return [parts[1], parts[2] || undefined, parts[3] || undefined] as const;
};
const applySlice = <T>(lines: T[], options?: ParseOptions): T[] => {
if (options && options.slice != null) {
if (Array.isArray(options.slice)) return lines.slice(options.slice[0], options.slice[1]);
return lines.slice(0, options.slice);
}
return lines;
};
export const parseV8OrIeString = (stack: string, options?: ParseOptions): StackFrame[] => {
const filteredLines = applySlice(
stack.split("\n").filter((line) => {
return !!line.match(CHROME_IE_STACK_REGEXP);
}),
options,
);
return filteredLines.map((line): StackFrame => {
let currentLine = line;
if (currentLine.includes("(eval ")) {
currentLine = currentLine
.replace(/eval code/g, "eval")
.replace(/(\(eval at [^()]*)|(,.*$)/g, "");
}
let sanitizedLine = currentLine
.replace(/^\s+/, "")
.replace(/\(eval code/g, "(")
.replace(/^.*?\s+/, "");
const locationMatch = sanitizedLine.match(/ (\(.+\)$)/);
sanitizedLine = locationMatch ? sanitizedLine.replace(locationMatch[0], "") : sanitizedLine;
const locationParts = extractLocation(locationMatch ? locationMatch[1] : sanitizedLine);
const functionName = (locationMatch && sanitizedLine) || undefined;
const fileName = ["eval", "<anonymous>"].includes(locationParts[0])
? undefined
: locationParts[0];
return {
functionName,
fileName,
lineNumber: locationParts[1] ? +locationParts[1] : undefined,
columnNumber: locationParts[2] ? +locationParts[2] : undefined,
source: currentLine,
};
});
};
export const parseFFOrSafariString = (stack: string, options?: ParseOptions): StackFrame[] => {
const filteredLines = applySlice(
stack.split("\n").filter((line) => {
return !line.match(SAFARI_NATIVE_CODE_REGEXP);
}),
options,
);
return filteredLines.map((line): StackFrame => {
let currentLine = line;
if (currentLine.includes(" > eval"))
currentLine = currentLine.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g, ":$1");
if (!currentLine.includes("@") && !currentLine.includes(":")) {
return {
functionName: currentLine,
};
} else {
const functionNameRegex =
/(([^\n\r"\u2028\u2029]*".[^\n\r"\u2028\u2029]*"[^\n\r@\u2028\u2029]*(?:@[^\n\r"\u2028\u2029]*"[^\n\r@\u2028\u2029]*)*(?:[\n\r\u2028\u2029][^@]*)?)?[^@]*)@/;
const matches = currentLine.match(functionNameRegex);
const functionName = matches && matches[1] ? matches[1] : undefined;
const locationParts = extractLocation(currentLine.replace(functionNameRegex, ""));
return {
functionName,
fileName: locationParts[0],
lineNumber: locationParts[1] ? +locationParts[1] : undefined,
columnNumber: locationParts[2] ? +locationParts[2] : undefined,
source: currentLine,
};
}
});
};

398
node_modules/bippy/src/source/symbolication.ts generated vendored Normal file
View File

@@ -0,0 +1,398 @@
import { decode, SourceMapMappings, type SourceMapSegment } from "@jridgewell/sourcemap-codec";
import { StackFrame } from "./parse-stack.js";
export interface DecodedSourceMapSection {
map: {
file?: string;
ignoredSourceIndices?: Set<number>;
mappings: SourceMapSegment[][];
names?: string[];
sourceRoot?: string;
sources: string[];
sourcesContent?: string[];
version: 3;
};
offset: {
column: number;
line: number;
};
}
// https://tc39.es/ecma426/#sec-index-source-map
export interface IndexSourceMap {
file?: string;
sections: Array<{
map: StandardSourceMap;
offset: {
column: number;
line: number;
};
}>;
version: 3;
}
export type RawSourceMap = IndexSourceMap | StandardSourceMap;
export interface SourceMap {
file?: string;
ignoredSourceIndices?: Set<number>;
mappings: SourceMapSegment[][];
names?: string[];
sections?: DecodedSourceMapSection[];
sourceRoot?: string;
sources: string[];
sourcesContent?: string[];
version: 3;
}
// https://developer.chrome.com/blog/sourcemaps#the_anatomy_of_a_source_map
export interface StandardSourceMap {
file?: string;
ignoreList?: number[];
mappings: string;
names?: string[];
sourceRoot?: string;
sources: string[];
sourcesContent?: string[];
version: 3;
x_google_ignoreList?: number[];
}
// has a scheme, e.g. http://, https://, file://, data:, etc.
// https://datatracker.ietf.org/doc/html/rfc3986#section-3.1
const SCHEME_REGEX = /^[a-zA-Z][a-zA-Z\d+\-.]*:/;
// inline sourcemap, e.g. data:application/json;base64,...
const INLINE_SOURCEMAP_REGEX = /^data:application\/json[^,]+base64,/;
// sourcemap url, e.g. //@ sourceMappingURL=... or /* @ sourceMappingURL=... */ at the end of the file
const SOURCEMAP_REGEX =
/(?:\/\/[@#][ \t]+sourceMappingURL=([^\s'"]+?)[ \t]*$)|(?:\/\*[@#][ \t]+sourceMappingURL=([^*]+?)[ \t]*(?:\*\/)[ \t]*$)/;
export const sourceMapCache = new Map<string, null | SourceMap>();
interface SourceMapResult {
sourceMap: null | SourceMap;
isTransientFailure: boolean;
}
const _pendingSourceMapRequests = new Map<string, Promise<SourceMapResult>>();
const getSourceFromMappings = (
mappings: SourceMapMappings,
sources: string[],
lineIndexInMappings: number,
column: number,
ignoredSourceIndices?: Set<number>,
): StackFrame | null => {
if (lineIndexInMappings < 0 || lineIndexInMappings >= mappings.length) {
return null;
}
const lineMapping = mappings[lineIndexInMappings];
if (!lineMapping || lineMapping.length === 0) {
return null;
}
// Segments within a line are sorted by generated column, so binary search for
// the last segment at or before the column.
let closestLineSegment: null | SourceMapSegment = null;
let lowIndex = 0;
let highIndex = lineMapping.length - 1;
while (lowIndex <= highIndex) {
const middleIndex = (lowIndex + highIndex) >> 1;
if (lineMapping[middleIndex][0] <= column) {
closestLineSegment = lineMapping[middleIndex];
lowIndex = middleIndex + 1;
} else {
highIndex = middleIndex - 1;
}
}
if (!closestLineSegment || closestLineSegment.length < 4) {
return null;
}
const [, sourceIndex, sourceLine, sourceColumn] = closestLineSegment;
if (sourceIndex === undefined || sourceLine === undefined || sourceColumn === undefined) {
return null;
}
const fileName = sources[sourceIndex];
if (!fileName) {
return null;
}
return {
columnNumber: sourceColumn,
fileName,
lineNumber: sourceLine + 1,
isIgnoreListed: ignoredSourceIndices?.has(sourceIndex) ?? false,
};
};
export const getSourceFromSourceMap = (
sourceMap: SourceMap,
line: number,
column: number,
): StackFrame | null => {
if (sourceMap.sections) {
// Section offsets are 0-based while stack trace lines are 1-based.
const lineIndex = line - 1;
let targetSection: DecodedSourceMapSection | null = null;
for (const section of sourceMap.sections) {
if (
lineIndex > section.offset.line ||
(lineIndex === section.offset.line && column >= section.offset.column)
) {
targetSection = section;
} else {
break;
}
}
if (!targetSection) {
return null;
}
const relativeLine = lineIndex - targetSection.offset.line;
const relativeColumn =
lineIndex === targetSection.offset.line ? column - targetSection.offset.column : column;
return getSourceFromMappings(
targetSection.map.mappings,
targetSection.map.sources,
relativeLine,
relativeColumn,
targetSection.map.ignoredSourceIndices,
);
}
return getSourceFromMappings(
sourceMap.mappings,
sourceMap.sources,
line - 1,
column,
sourceMap.ignoredSourceIndices,
);
};
const getSourceMapUrl = (url: string, content: string): null | string => {
// Walk lines backwards without content.split("\n"), which would allocate a
// string per line of the entire bundle.
let sourceMapUrl: string | undefined;
let searchEnd = content.length;
while (searchEnd > 0 && !sourceMapUrl) {
const lineStart = content.lastIndexOf("\n", searchEnd - 1) + 1;
const regexMatch = content.slice(lineStart, searchEnd).match(SOURCEMAP_REGEX);
if (regexMatch) {
sourceMapUrl = regexMatch[1] || regexMatch[2];
}
searchEnd = lineStart - 1;
}
if (!sourceMapUrl) {
return null;
}
const hasScheme = SCHEME_REGEX.test(sourceMapUrl);
if (!(INLINE_SOURCEMAP_REGEX.test(sourceMapUrl) || hasScheme || sourceMapUrl.startsWith("/"))) {
const urlSegments = url.split("/");
urlSegments[urlSegments.length - 1] = sourceMapUrl;
sourceMapUrl = urlSegments.join("/");
}
return sourceMapUrl;
};
const getIgnoredSourceIndices = (rawSourceMap: StandardSourceMap): Set<number> | undefined => {
const ignoreList = rawSourceMap.ignoreList ?? rawSourceMap.x_google_ignoreList;
return Array.isArray(ignoreList) && ignoreList.length > 0 ? new Set(ignoreList) : undefined;
};
const decodeStandardSourceMap = (rawSourceMap: StandardSourceMap): SourceMap => ({
file: rawSourceMap.file,
ignoredSourceIndices: getIgnoredSourceIndices(rawSourceMap),
mappings: decode(rawSourceMap.mappings),
names: rawSourceMap.names,
sourceRoot: rawSourceMap.sourceRoot,
sources: rawSourceMap.sources,
sourcesContent: rawSourceMap.sourcesContent,
version: 3,
});
const decodeIndexSourceMap = (rawSourceMap: IndexSourceMap): SourceMap => {
const decodedSections: DecodedSourceMapSection[] = rawSourceMap.sections.map(
({ map, offset }) => ({
map: {
...map,
ignoredSourceIndices: getIgnoredSourceIndices(map),
mappings: decode(map.mappings),
},
offset,
}),
);
const allSources = new Set<string>();
for (const section of decodedSections) {
for (const source of section.map.sources) {
allSources.add(source);
}
}
return {
file: rawSourceMap.file,
mappings: [],
names: [],
sections: decodedSections,
sourceRoot: undefined,
sources: Array.from(allSources),
sourcesContent: undefined,
version: 3,
};
};
const isFetchableUrl = (url: string): boolean => {
if (!url) {
return false;
}
const trimmedUrl = url.trim();
if (!trimmedUrl) {
return false;
}
const schemeMatch = trimmedUrl.match(SCHEME_REGEX);
if (!schemeMatch) {
return true;
}
const scheme = schemeMatch[0].toLowerCase();
return scheme === "http:" || scheme === "https:";
};
// Resolves a bundle's source map, or null when the bundle definitively has
// none. A thrown fetch (network error or aborted request) is left to propagate
// so getSourceMap can treat it as transient and avoid caching it: a non-ok
// response, a missing sourceMappingURL, or an undecodable map are definitive and
// return null, but a dropped connection is not and must stay retryable.
export const getSourceMapImpl = async (
bundleUrl: string,
fetchFn: (url: string) => Promise<Response> = fetch,
): Promise<null | SourceMap> => {
if (!isFetchableUrl(bundleUrl)) {
return null;
}
const bundleResponse = await fetchFn(bundleUrl);
if (!bundleResponse.ok) {
return null;
}
const bundleContent = await bundleResponse.text();
if (!bundleContent) {
return null;
}
const sourceMapUrl = getSourceMapUrl(bundleUrl, bundleContent);
if (!sourceMapUrl) return null;
// inline data: maps (vite dev, babel inline sourcemaps) are decoded by
// fetch itself, so they bypass the network-url check
if (!isFetchableUrl(sourceMapUrl) && !INLINE_SOURCEMAP_REGEX.test(sourceMapUrl)) {
return null;
}
const sourceMapResponse = await fetchFn(sourceMapUrl);
if (!sourceMapResponse.ok) {
return null;
}
try {
const rawSourceMap = (await sourceMapResponse.json()) as RawSourceMap;
return "sections" in rawSourceMap
? decodeIndexSourceMap(rawSourceMap)
: decodeStandardSourceMap(rawSourceMap);
} catch {
return null;
}
};
export const getSourceMap = async (
file: string,
useCache = true,
fetchFn?: (url: string) => Promise<Response>,
): Promise<null | SourceMap> => {
if (useCache && sourceMapCache.has(file)) {
return sourceMapCache.get(file) ?? null;
}
const pendingRequest = useCache ? _pendingSourceMapRequests.get(file) : undefined;
if (pendingRequest) {
return (await pendingRequest).sourceMap;
}
// A transient fetch failure (aborted request or network error) rejects; a
// definitive "no map" resolves to null. Only definitive results are cached:
// caching a transient null would pin the bundle to a degraded result for the
// rest of the page's lifetime, even after the network recovers.
const fetchPromise: Promise<SourceMapResult> = getSourceMapImpl(file, fetchFn).then(
(sourceMap) => ({ sourceMap, isTransientFailure: false }),
() => ({ sourceMap: null, isTransientFailure: true }),
);
if (useCache) {
_pendingSourceMapRequests.set(file, fetchPromise);
}
const { sourceMap, isTransientFailure } = await fetchPromise;
if (useCache) {
_pendingSourceMapRequests.delete(file);
if (!isTransientFailure) {
sourceMapCache.set(file, sourceMap);
}
}
return sourceMap;
};
export const symbolicateStack = async (
stack: StackFrame[],
cache = true,
fetchFn?: (url: string) => Promise<Response>,
): Promise<StackFrame[]> => {
return await Promise.all(
stack.map(async (stackFrame) => {
if (!stackFrame.fileName) return stackFrame;
const sourceMap = await getSourceMap(stackFrame.fileName, cache, fetchFn);
if (
!sourceMap ||
typeof stackFrame.lineNumber !== "number" ||
typeof stackFrame.columnNumber !== "number"
) {
return stackFrame;
}
const symbolicatedSource = getSourceFromSourceMap(
sourceMap,
stackFrame.lineNumber,
stackFrame.columnNumber,
);
if (!symbolicatedSource) return stackFrame;
return {
...stackFrame,
source:
symbolicatedSource.fileName && stackFrame.source
? stackFrame.source.replace(stackFrame.fileName, symbolicatedSource.fileName)
: stackFrame.source,
fileName: symbolicatedSource.fileName,
lineNumber: symbolicatedSource.lineNumber,
columnNumber: symbolicatedSource.columnNumber,
isIgnoreListed: symbolicatedSource.isIgnoreListed,
isSymbolicated: true,
};
}),
);
};

6
node_modules/bippy/src/source/types.ts generated vendored Normal file
View File

@@ -0,0 +1,6 @@
export interface FiberSource {
columnNumber?: number;
fileName: string;
lineNumber?: number;
functionName?: string;
}

438
node_modules/bippy/src/types.ts generated vendored Normal file
View File

@@ -0,0 +1,438 @@
import type { ReactNode } from "react";
// @types/react-reconciler uses `export = ReactReconciler` (CJS namespace),
// which downstream bundlers can't resolve as ESM exports. These types are
// inlined from @types/react-reconciler@0.28 to avoid the dependency.
// Simple type aliases — most are opaque in the original
export type BundleType = 0 | 1;
export type Flags = number;
export type Lanes = number;
export type TypeOfMode = number;
export type RootTag = 0 | 1 | 2;
export type LanePriority =
| 0
| 1
| 2
| 3
| 4
| 5
| 6
| 7
| 8
| 9
| 10
| 11
| 12
| 13
| 14
| 15
| 16
| 17;
export type WorkTag =
| 0
| 1
| 2
| 3
| 4
| 5
| 6
| 7
| 8
| 9
| 10
| 11
| 12
| 13
| 14
| 15
| 16
| 17
| 18
| 19
| 20
| 21
| 22
| 23
| 24
| 25
| 26
| 27
| 28
| 29
| 30
| 31;
export type HookType =
| "useState"
| "useReducer"
| "useContext"
| "useRef"
| "useEffect"
| "useLayoutEffect"
| "useCallback"
| "useMemo"
| "useImperativeHandle"
| "useDebugValue"
| "useDeferredValue"
| "useTransition"
| "useMutableSource"
| "useOpaqueIdentifier"
| "useCacheRefresh";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type FiberRoot = any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type MutableSource = any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type OpaqueHandle = any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type OpaqueRoot = any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type React$AbstractComponent<_Config, _Instance = unknown> = any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type HostConfig = Record<string, any>;
// Structural interfaces
export interface Source {
fileName: string;
lineNumber: number;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export interface RefObject {
current: any;
}
export interface Thenable<T> {
then(resolve: () => T, reject?: () => T): T;
}
export interface ReactContext<T> {
$$typeof: symbol | number;
Consumer: ReactContext<T>;
Provider: ReactProviderType<T>;
_calculateChangedBits: ((a: T, b: T) => number) | null;
_currentValue: T;
_currentValue2: T;
_threadCount: number;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
_currentRenderer?: Record<string, any> | null;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
_currentRenderer2?: Record<string, any> | null;
displayName?: string;
}
export interface ReactProviderType<T> {
$$typeof: symbol | number;
_context: ReactContext<T>;
}
export interface ReactProvider<T> {
$$typeof: symbol | number;
type: ReactProviderType<T>;
key: null | string;
ref: null;
props: { value: T; children?: ReactNode };
}
export interface ReactConsumer<T> {
$$typeof: symbol | number;
type: ReactContext<T>;
key: null | string;
ref: null;
props: { children: (value: T) => ReactNode; unstable_observedBits?: number };
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export interface ReactPortal {
$$typeof: symbol | number;
key: null | string;
containerInfo: any;
children: ReactNode;
implementation: any;
}
export interface ComponentSelector {
$$typeof: symbol | number;
value: React$AbstractComponent<never, unknown>;
}
export interface HasPseudoClassSelector {
$$typeof: symbol | number;
value: Selector[];
}
export interface RoleSelector {
$$typeof: symbol | number;
value: string;
}
export interface TextSelector {
$$typeof: symbol | number;
value: string;
}
export interface TestNameSelector {
$$typeof: symbol | number;
value: string;
}
export type Selector =
| ComponentSelector
| HasPseudoClassSelector
| RoleSelector
| TextSelector
| TestNameSelector;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export interface DevToolsConfig<
Instance = any,
TextInstance = any,
RendererInspectionConfig = any,
> {
bundleType: BundleType;
version: string;
rendererPackageName: string;
findFiberByHostInstance?: (instance: Instance | TextInstance) => ReactFiber | null;
rendererConfig?: RendererInspectionConfig;
}
export interface SuspenseHydrationCallbacks<SuspenseInstance = unknown> {
onHydrated?: (suspenseInstance: SuspenseInstance) => void;
onDeleted?: (suspenseInstance: SuspenseInstance) => void;
}
export interface TransitionTracingCallbacks {
onTransitionStart?: (transitionName: string, startTime: number) => void;
onTransitionProgress?: (
transitionName: string,
startTime: number,
currentTime: number,
pending: Array<{ name: null | string }>,
) => void;
onTransitionIncomplete?: (
transitionName: string,
startTime: number,
deletions: Array<{ type: string; name?: string; newName?: string; endTime: number }>,
) => void;
onTransitionComplete?: (transitionName: string, startTime: number, endTime: number) => void;
onMarkerProgress?: (
transitionName: string,
marker: string,
startTime: number,
currentTime: number,
pending: Array<{ name: null | string }>,
) => void;
onMarkerIncomplete?: (
transitionName: string,
marker: string,
startTime: number,
deletions: Array<{ type: string; name?: string; newName?: string; endTime: number }>,
) => void;
onMarkerComplete?: (
transitionName: string,
marker: string,
startTime: number,
endTime: number,
) => void;
}
// The base Fiber interface from react-reconciler, used to derive bippy's Fiber below
interface ReactFiber {
tag: WorkTag;
key: null | string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
elementType: any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type: any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
stateNode: any;
return: ReactFiber | null;
child: ReactFiber | null;
sibling: ReactFiber | null;
index: number;
ref: null | (((handle: unknown) => void) & { _stringRef?: string | null }) | RefObject;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
pendingProps: any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
memoizedProps: any;
updateQueue: unknown;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
memoizedState: any;
dependencies: Dependencies | null;
mode: TypeOfMode;
flags: Flags;
subtreeFlags: Flags;
deletions: ReactFiber[] | null;
nextEffect: ReactFiber | null;
firstEffect: ReactFiber | null;
lastEffect: ReactFiber | null;
lanes: Lanes;
childLanes: Lanes;
alternate: ReactFiber | null;
actualDuration?: number;
actualStartTime?: number;
selfBaseDuration?: number;
treeBaseDuration?: number;
_debugID?: number;
_debugSource?: Source | null;
_debugOwner?: ReactFiber | null;
_debugIsCurrentlyTiming?: boolean;
_debugNeedsRemount?: boolean;
_debugHookTypes?: HookType[] | null;
}
// ── bippy types (not from react-reconciler) ──
export interface ContextDependency<T> {
context: ReactContext<T>;
memoizedValue: T;
next: ContextDependency<unknown> | null;
observedBits: number;
}
export interface Dependencies {
firstContext: ContextDependency<unknown> | null;
lanes: Lanes;
}
export interface Effect {
[key: string]: unknown;
create: (...args: unknown[]) => unknown;
deps: null | unknown[];
destroy: ((...args: unknown[]) => unknown) | null;
next: Effect | null;
tag: number;
}
export interface Family {
current: unknown;
}
/**
* React 19 flight metadata for a server component owner (ReactComponentInfo).
* Unlike client owners it has no `tag`; the owner chain continues via `owner`.
*/
export interface ServerComponentInfo {
name?: string;
env?: string;
owner?: Fiber | ServerComponentInfo | null;
debugStack?: Error | null;
}
export interface RendererRefreshUpdate {
staleFamilies: Set<Family>;
updatedFamilies: Set<Family>;
}
/**
* Represents a react-internal Fiber node.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type Fiber<T = any> = Omit<
ReactFiber,
| "alternate"
| "child"
| "dependencies"
| "memoizedProps"
| "memoizedState"
| "pendingProps"
| "return"
| "sibling"
| "stateNode"
| "updateQueue"
> & {
_debugInfo?: Array<{
debugLocation?: unknown;
env?: string;
name?: string;
}>;
_debugOwner?: Fiber;
// react <19
_debugSource?: {
columnNumber?: number;
fileName: string;
lineNumber: number;
};
// react 19+
// https://github.com/facebook/react/issues/29092?utm_source=chatgpt.com
_debugStack?: Error & { stack: string };
alternate: Fiber | null;
child: Fiber | null;
dependencies: Dependencies | null;
memoizedProps: Props;
memoizedState: MemoizedState;
pendingProps: Props;
return: Fiber | null;
sibling: Fiber | null;
stateNode: T;
updateQueue: {
[key: string]: unknown;
lastEffect: Effect | null;
};
};
export interface MemoizedState {
[key: string]: unknown;
memoizedState: unknown;
next: MemoizedState | null;
}
export interface Props {
[key: string]: unknown;
}
export interface ReactDevToolsGlobalHook {
_instrumentationIsActive?: boolean;
_instrumentationSource?: string;
checkDCE: (fn: unknown) => void;
hasUnsupportedRendererAttached: boolean;
inject: (renderer: ReactRenderer) => number;
// https://github.com/aidenybai/bippy/issues/43
on: () => void;
onCommitFiberRoot: (rendererID: number, root: FiberRoot, priority: number | void) => void;
onCommitFiberUnmount: (rendererID: number, fiber: Fiber) => void;
onPostCommitFiberRoot: (rendererID: number, root: FiberRoot) => void;
// called by dev builds of react-reconciler on root schedule; absent from
// the hook react-refresh installs, so it stays optional
onScheduleFiberRoot?: (rendererID: number, root: FiberRoot, children: ReactNode) => void;
renderers: Map<number, ReactRenderer>;
supportsFiber: boolean;
supportsFlight: boolean;
}
// https://github.com/facebook/react/blob/6a4b46cd70d2672bc4be59dcb5b8dede22ed0cef/packages/react-devtools-shared/src/backend/types.js
export interface ReactRenderer {
bundleType: 0 /* PROD */ | 1 /* DEV */;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
currentDispatcherRef: any;
// dev only: https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberReconciler.js#L842
findFiberByHostInstance?: (hostInstance: unknown) => Fiber | null;
// react devtools
getCurrentFiber?: (fiber: Fiber) => Fiber | null;
overrideContext?: (fiber: Fiber, contextType: unknown, path: string[], value: unknown) => void;
overrideHookState?: (fiber: Fiber, id: string, path: string[], value: unknown) => void;
overrideHookStateDeletePath?: (fiber: Fiber, id: number, path: Array<number | string>) => void;
overrideHookStateRenamePath?: (
fiber: Fiber,
id: number,
oldPath: Array<number | string>,
newPath: Array<number | string>,
) => void;
overrideProps?: (fiber: Fiber, path: string[], value: unknown) => void;
overridePropsDeletePath?: (fiber: Fiber, path: Array<number | string>) => void;
overridePropsRenamePath?: (
fiber: Fiber,
oldPath: Array<number | string>,
newPath: Array<number | string>,
) => void;
reconcilerVersion: string;
rendererPackageName: string;
// react refresh
scheduleRefresh?: (root: FiberRoot, update: RendererRefreshUpdate) => void;
scheduleRoot?: (root: FiberRoot, element: React.ReactNode) => void;
scheduleUpdate?: (fiber: Fiber) => void;
setErrorHandler?: (newShouldErrorImpl: (fiber: Fiber) => boolean) => void;
setRefreshHandler?: (handler: ((fiber: Fiber) => Family | null) | null) => void;
setSuspenseHandler?: (newShouldSuspendImpl: (suspenseInstance: unknown) => void) => void;
version: string;
}
declare global {
// eslint-disable-next-line no-var
var __REACT_DEVTOOLS_GLOBAL_HOOK__: ReactDevToolsGlobalHook | undefined;
}

17
node_modules/bippy/src/unsubscribe.ts generated vendored Normal file
View File

@@ -0,0 +1,17 @@
export interface Unsubscribe extends Disposable {
(): void;
}
/**
* Wraps a teardown callback so it is both callable and a `Disposable`,
* letting subscriptions compose through explicit resource management:
*
* @example
* ```ts
* using instrumentation = instrument({ onCommitFiberRoot });
* using refresh = instrumentReactRefresh({ onRefresh: handleRefresh });
* // both torn down automatically at scope exit
* ```
*/
export const toUnsubscribe = (dispose: () => void): Unsubscribe =>
Object.assign(dispose, { [Symbol.dispose]: dispose });