Installation
npm install element-sourceQuick Start
Pass any DOM element to resolveElementInfo to get its source file location, component name, and full component stack.
import { resolveElementInfo } from "element-source";
const info = await resolveElementInfo(element);
// {
// tagName: "button",
// componentName: "App",
// source: { filePath: "src/App.tsx", lineNumber: 42, columnNumber: 10, componentName: "App" },
// stack: [...]
// }API
resolveElementInfo(node: object): Promise<ElementInfo>
Returns complete metadata: tag name, component name, source location, and full stack.
const info = await resolveElementInfo(document.querySelector("#root button"));
// {
// tagName: "button",
// componentName: "Counter",
// source: { filePath: "src/Counter.tsx", lineNumber: 12, columnNumber: 5, componentName: "Counter" },
// stack: [
// { filePath: "src/Counter.tsx", lineNumber: 12, columnNumber: 5, componentName: "Counter" },
// { filePath: "src/App.tsx", lineNumber: 8, columnNumber: 3, componentName: "App" },
// ]
// }resolveSource(node: object): Promise<ElementSourceInfo | null>
Returns the primary source location.
const source = await resolveSource(element);
// { filePath: "src/Counter.tsx", lineNumber: 12, columnNumber: 5, componentName: "Counter" }resolveStack(node: object): Promise<ElementSourceInfo[]>
Returns the full stack of source frames (React + framework combined).
const stack = await resolveStack(element);
// [
// { filePath: "src/Counter.tsx", lineNumber: 12, columnNumber: 5, componentName: "Counter" },
// { filePath: "src/App.tsx", lineNumber: 8, columnNumber: 3, componentName: "App" },
// ]resolveComponentName(node: object): Promise<string | null>
Returns the nearest user-defined component name.
const name = await resolveComponentName(element);
// "Counter"createSourceResolver(options?: ResolverOptions)
Creates a resolver with custom framework resolvers.
import { createSourceResolver, svelteResolver, vueResolver } from "element-source";
const { resolveSource, resolveStack, resolveComponentName, resolveElementInfo } =
createSourceResolver({
resolvers: [svelteResolver, vueResolver],
});
const info = await resolveElementInfo(element);formatStackFrame(frame: ElementSourceInfo): string
Formats a single source frame as a stack-trace-style string.
const frame = { filePath: "src/App.tsx", lineNumber: 42, columnNumber: 10, componentName: "App" };
formatStackFrame(frame);
// "\n in App (at src/App.tsx:42:10)"formatStack(stack: ElementSourceInfo[], maxLines?: number): string
Formats an array of source frames.
const stack = [
{ filePath: "src/Counter.tsx", lineNumber: 12, columnNumber: 5, componentName: "Counter" },
{ filePath: "src/App.tsx", lineNumber: 8, columnNumber: 3, componentName: "App" },
];
formatStack(stack);
// "\n in Counter (at src/Counter.tsx:12:5)\n in App (at src/App.tsx:8:3)"
formatStack(stack, 1);
// "\n in Counter (at src/Counter.tsx:12:5)"getTagName(node: object): string
Returns the tag name from any host instance. Handles DOM Element.tagName, Ink nodeName, and falls back to "".
getTagName(document.createElement("div")); // "div"
getTagName({ nodeName: "ink-text" }); // "ink-text"
getTagName({}); // ""