react-grep 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -52,26 +52,93 @@ var isSameOrigin = (a, b) => {
52
52
  return false;
53
53
  }
54
54
  };
55
+ var fetchSourceMapJson = async (ref, baseUrl) => {
56
+ if (ref.startsWith("data:")) {
57
+ const dataMatch = DATA_URI_RE.exec(ref);
58
+ return dataMatch ? atob(dataMatch[1]) : null;
59
+ }
60
+ const mapUrl = new URL(ref, baseUrl).href;
61
+ if (!isSameOrigin(baseUrl, mapUrl)) return null;
62
+ const mapRes = await fetch(mapUrl);
63
+ if (!mapRes.ok) return null;
64
+ return mapRes.text();
65
+ };
66
+ var flattenIndexedMap = (sections) => {
67
+ const allSources = [];
68
+ const allMappings = [];
69
+ for (const section of sections) {
70
+ const decoded = decodeMappings(section.map.mappings);
71
+ const lineOff = section.offset.line;
72
+ const colOff = section.offset.column;
73
+ const srcOff = allSources.length;
74
+ while (allMappings.length < lineOff + decoded.length) allMappings.push([]);
75
+ for (let i = 0; i < decoded.length; i++) {
76
+ const target = allMappings[lineOff + i];
77
+ for (const seg of decoded[i]) {
78
+ target.push([i === 0 ? seg[0] + colOff : seg[0], seg[1] + srcOff, seg[2], seg[3]]);
79
+ }
80
+ }
81
+ allSources.push(...section.map.sources);
82
+ }
83
+ for (const line of allMappings) {
84
+ if (line.length > 1) line.sort((a, b) => a[0] - b[0]);
85
+ }
86
+ return { sources: allSources, mappings: allMappings };
87
+ };
88
+ var parseSourceMap = (json) => {
89
+ try {
90
+ const raw = JSON.parse(json);
91
+ if (Array.isArray(raw.sections)) return flattenIndexedMap(raw.sections);
92
+ if (!raw.sources || !raw.mappings) return null;
93
+ return { sources: raw.sources, mappings: decodeMappings(raw.mappings) };
94
+ } catch {
95
+ return null;
96
+ }
97
+ };
55
98
  var fetchAndParse = async (url) => {
56
99
  try {
57
100
  const res = await fetch(url);
58
101
  const text = await res.text();
59
102
  const match = text.match(/\/\/[#@]\s*sourceMappingURL=([^\s]+)$/m);
60
- if (!match) return null;
61
- const ref = match[1].trim();
62
- let mapJson;
63
- if (ref.startsWith("data:")) {
64
- const dataMatch = DATA_URI_RE.exec(ref);
65
- if (!dataMatch) return null;
66
- mapJson = atob(dataMatch[1]);
67
- } else {
68
- const mapUrl = new URL(ref, url).href;
69
- if (!isSameOrigin(url, mapUrl)) return null;
70
- const mapRes = await fetch(mapUrl);
71
- mapJson = await mapRes.text();
103
+ if (match) {
104
+ const json = await fetchSourceMapJson(match[1].trim(), url);
105
+ if (json) {
106
+ const map = parseSourceMap(json);
107
+ if (map) return map;
108
+ }
72
109
  }
73
- const raw = JSON.parse(mapJson);
74
- return { sources: raw.sources, mappings: decodeMappings(raw.mappings) };
110
+ const headerRef = res.headers.get("SourceMap") ?? res.headers.get("X-SourceMap");
111
+ if (headerRef) {
112
+ const json = await fetchSourceMapJson(headerRef.trim(), url);
113
+ if (json) {
114
+ const map = parseSourceMap(json);
115
+ if (map) return map;
116
+ }
117
+ }
118
+ const conventionRes = await fetch(`${url}.map`);
119
+ if (conventionRes.ok) {
120
+ const json = await conventionRes.text();
121
+ return parseSourceMap(json);
122
+ }
123
+ return null;
124
+ } catch {
125
+ return null;
126
+ }
127
+ };
128
+ var ABOUT_SERVER_RE = /^about:\/\/React\/Server\/file:\/\/\//;
129
+ var NEXT_DOTDIR_RE = /[/\\](\.next[/\\].+?)(?:\?.*)?$/;
130
+ var fetchAndParseServerFile = async (url) => {
131
+ try {
132
+ const filePath = decodeURIComponent(url.replace(ABOUT_SERVER_RE, ""));
133
+ const dotNextMatch = NEXT_DOTDIR_RE.exec(filePath);
134
+ if (!dotNextMatch) return null;
135
+ const origin = typeof location !== "undefined" ? location.origin : "";
136
+ const mapUrl = `${origin}/__nextjs_source-map?filename=${encodeURIComponent(dotNextMatch[1])}`;
137
+ const res = await fetch(mapUrl);
138
+ if (!res.ok) return null;
139
+ const json = await res.text();
140
+ if (!json) return null;
141
+ return parseSourceMap(json);
75
142
  } catch {
76
143
  return null;
77
144
  }
@@ -79,7 +146,7 @@ var fetchAndParse = async (url) => {
79
146
  var getSourceMap = (url) => {
80
147
  let promise = cache.get(url);
81
148
  if (!promise) {
82
- promise = fetchAndParse(url);
149
+ promise = ABOUT_SERVER_RE.test(url) ? fetchAndParseServerFile(url) : fetchAndParse(url);
83
150
  cache.set(url, promise);
84
151
  }
85
152
  return promise;
@@ -102,7 +169,10 @@ var resolveOriginalPosition = async (url, line, column) => {
102
169
  if (!map) return null;
103
170
  const seg = lookup(map, line - 1, column - 1);
104
171
  if (!seg) return null;
105
- const fileName = map.sources[seg[1]];
172
+ let fileName = map.sources[seg[1]];
173
+ if (fileName.startsWith("file:///")) {
174
+ fileName = decodeURIComponent(new URL(fileName).pathname);
175
+ }
106
176
  return {
107
177
  fileName,
108
178
  lineNumber: seg[2] + 1,
@@ -111,6 +181,7 @@ var resolveOriginalPosition = async (url, line, column) => {
111
181
  };
112
182
 
113
183
  // src/fiber.ts
184
+ var isServerComponent = (owner) => "env" in owner && typeof owner.name === "string";
114
185
  var COMPOSITE_TAGS = /* @__PURE__ */ new Set([
115
186
  0,
116
187
  // FunctionComponent
@@ -167,7 +238,8 @@ var SKIP_FRAMES = /* @__PURE__ */ new Set([
167
238
  "jsxs",
168
239
  "jsx",
169
240
  "react-stack-top-frame",
170
- "react_stack_bottom_frame"
241
+ "react_stack_bottom_frame",
242
+ "fakeJSXCallSite"
171
243
  ]);
172
244
  var FRAME_RE = /at (?:(\S+) )?\(?(.+):(\d+):(\d+)\)?$/;
173
245
  var parseFirstUserFrame = (fiber) => {
@@ -232,7 +304,7 @@ var getComponentInfo = async (el) => {
232
304
  }
233
305
  const owner = domFiber._debugOwner;
234
306
  const elementTag = typeof domFiber.type === "string" ? domFiber.type : null;
235
- if (owner && owner === composite) {
307
+ if (owner && !isServerComponent(owner) && owner === composite) {
236
308
  return {
237
309
  kind: "element",
238
310
  name: getComponentName(owner),
@@ -241,10 +313,12 @@ var getComponentInfo = async (el) => {
241
313
  callSite: await getCompositeDebugSource(composite)
242
314
  };
243
315
  }
244
- const nameSource = owner && COMPOSITE_TAGS.has(owner.tag) ? owner : composite;
316
+ const name = owner && isServerComponent(owner) ? owner.name : getComponentName(
317
+ owner && !isServerComponent(owner) && COMPOSITE_TAGS.has(owner.tag) ? owner : composite
318
+ );
245
319
  return {
246
320
  kind: "children",
247
- name: getComponentName(nameSource),
321
+ name,
248
322
  elementTag,
249
323
  source: await getDomDebugSource(domFiber),
250
324
  callSite: null
@@ -295,8 +369,8 @@ var applyStyles = (el, styles) => {
295
369
  };
296
370
  var truncatePath = (filePath) => {
297
371
  const parts = filePath.split("/");
298
- if (parts.length <= 3) return filePath;
299
- return `.../${parts.slice(-3).join("/")}`;
372
+ if (parts.length <= 2) return filePath;
373
+ return `.../${parts.slice(-2).join("/")}`;
300
374
  };
301
375
  var createSpan = (text, styles) => {
302
376
  const span = document.createElement("span");
@@ -371,11 +445,11 @@ var OverlayManager = class {
371
445
  this.tooltip.style.left = `${Math.max(4, left)}px`;
372
446
  this.tooltip.style.display = "block";
373
447
  }
374
- showCopied(location) {
448
+ showCopied(location2) {
375
449
  if (!this.tooltip) return;
376
450
  this.tooltip.textContent = "";
377
451
  this.tooltip.appendChild(createSpan("Copied!", { color: "#4ade80", fontWeight: "600" }));
378
- this.tooltip.appendChild(createSpan(` ${truncatePath(location)}`, { color: "#a1a1aa" }));
452
+ this.tooltip.appendChild(createSpan(` ${truncatePath(location2)}`, { color: "#a1a1aa" }));
379
453
  this.tooltip.style.display = "block";
380
454
  setTimeout(() => this.hide(), 1500);
381
455
  }
@@ -471,9 +545,9 @@ var Inspector = class {
471
545
  const source = this.getActiveCopySource(info);
472
546
  if (!source) return;
473
547
  const { fileName, lineNumber, columnNumber } = source;
474
- const location = columnNumber != null ? `${fileName}:${lineNumber}:${columnNumber}` : `${fileName}:${lineNumber}`;
475
- await this.copyToClipboard(location);
476
- this.overlay.showCopied(location);
548
+ const location2 = columnNumber != null ? `${fileName}:${lineNumber}:${columnNumber}` : `${fileName}:${lineNumber}`;
549
+ await this.copyToClipboard(location2);
550
+ this.overlay.showCopied(location2);
477
551
  }
478
552
  handleKeyDown(e) {
479
553
  if (e.key === "Shift" && this.isModifierHeld(e)) {
@@ -1,3 +1,3 @@
1
- var ReactGrep=(function(exports){'use strict';var x=new Map,k="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",E=[];for(let e=0;e<k.length;e++)E[k.charCodeAt(e)]=e;var d=(e,t)=>{let n=0,i=0;for(;t.i<e.length;){let o=E[e.charCodeAt(t.i++)];if(i+=(o&31)<<n,!(o&32))return i&1?-(i>>1):i>>1;n+=5;}return 0},L=e=>{let t=[],n=0,i=0,o=0;for(let s of e.split(";")){let l=[],a=0;if(s){let r={i:0};for(;r.i<s.length;){if(s.charCodeAt(r.i)===44){r.i++;continue}a+=d(s,r),!(r.i>=s.length||s.charCodeAt(r.i)===44)&&(n+=d(s,r),i+=d(s,r),o+=d(s,r),r.i<s.length&&s.charCodeAt(r.i)!==44&&d(s,r),l.push([a,n,i,o]));}}t.push(l);}return t},_=/^data:application\/json[^,]*;base64,([A-Za-z0-9+/=]+)$/,A=(e,t)=>{try{return new URL(e).origin===new URL(t).origin}catch{return false}},H=async e=>{try{let i=(await(await fetch(e)).text()).match(/\/\/[#@]\s*sourceMappingURL=([^\s]+)$/m);if(!i)return null;let o=i[1].trim(),s;if(o.startsWith("data:")){let a=_.exec(o);if(!a)return null;s=atob(a[1]);}else {let a=new URL(o,e).href;if(!A(e,a))return null;s=await(await fetch(a)).text();}let l=JSON.parse(s);return {sources:l.sources,mappings:L(l.mappings)}}catch{return null}},O=e=>{let t=x.get(e);return t||(t=H(e),x.set(e,t)),t},K=(e,t,n)=>{if(t<0||t>=e.mappings.length)return null;let i=e.mappings[t];if(!i.length)return null;let o=0,s=i.length-1;for(;o<s;){let l=o+s+1>>1;i[l][0]<=n?o=l:s=l-1;}return i[o]},M=async(e,t,n)=>{let i=await O(e);if(!i)return null;let o=K(i,t-1,n-1);return o?{fileName:i.sources[o[1]],lineNumber:o[2]+1,columnNumber:o[3]+1}:null};var b=new Set([0,1,11,14,15]),U=e=>{try{let t=Object.keys(e).find(n=>n.startsWith("__reactFiber$"));return t?e[t]:null}catch{return null}},j=e=>{let t=e;for(;t;){if(b.has(t.tag))return t;t=t.return;}return null},W=e=>{if(typeof e=="function")return e;if(e&&typeof e=="object"){if("render"in e&&typeof e.render=="function")return e.render;if("type"in e&&typeof e.type=="function")return e.type}return null},y=e=>{let{type:t}=e;if(typeof t=="function")return t.displayName||t.name||"Anonymous";if(t&&typeof t=="object"){if("displayName"in t&&t.displayName)return t.displayName;let n=W(t);if(n)return n.displayName||n.name||"Anonymous"}return "Anonymous"},G=new Set(["jsxDEV","jsxs","jsx","react-stack-top-frame","react_stack_bottom_frame"]),z=/at (?:(\S+) )?\(?(.+):(\d+):(\d+)\)?$/,v=e=>{let t=e._debugStack?.stack;if(!t)return null;for(let n of t.split(`
2
- `)){let i=z.exec(n.trim());if(!i)continue;let[,o,s,l,a]=i;if(!(o&&G.has(o))&&!s.includes("/node_modules/"))return {url:s,line:Number(l),column:Number(a)}}return null},S=async e=>{let t=await M(e.url,e.line,e.column);if(t)return t;let n=e.url;try{let i=new URL(e.url);n=decodeURIComponent(i.pathname);let o=n.indexOf("?");o!==-1&&(n=n.substring(0,o));}catch{}return n=n.replace(/\.\.\//g,""),n.startsWith("/")&&(n=n.substring(1)),{fileName:n,lineNumber:e.line,columnNumber:e.column}},T=async e=>{if(e._debugSource)return e._debugSource;if(e._debugOwner?._debugSource)return e._debugOwner._debugSource;let t=v(e);if(t)return S(t);if(e._debugOwner){let n=v(e._debugOwner);if(n)return S(n)}return null},F=async e=>{if(e._debugSource)return e._debugSource;let t=v(e);return t?S(t):null},w=async e=>{let t=U(e);if(!t)return null;let n=j(t);if(!n)return null;if(t.return!=null&&b.has(t.return.tag))return {kind:"component",name:y(n),elementTag:null,source:await T(n),callSite:null};let o=t._debugOwner,s=typeof t.type=="string"?t.type:null;if(o&&o===n)return {kind:"element",name:y(o),elementTag:s,source:await F(t),callSite:await T(n)};let l=o&&b.has(o.tag)?o:n;return {kind:"children",name:y(l),elementTag:s,source:await F(t),callSite:null}};var Y=typeof navigator<"u"&&/Mac|iPhone|iPad/.test(navigator.platform),c={name:"#93c5fd",tag:"#a78bfa",path:"#71717a",pathActive:"#a1a1aa",pathDim:"#3f3f46",hint:"#52525b"},V={position:"fixed",pointerEvents:"none",zIndex:"2147483646",backgroundColor:"rgba(66, 135, 245, 0.15)",border:"1.5px solid rgba(66, 135, 245, 0.6)",borderRadius:"3px",display:"none",transition:"top 60ms ease-out, left 60ms ease-out, width 60ms ease-out, height 60ms ease-out"},B={position:"fixed",pointerEvents:"none",zIndex:"2147483647",display:"none",fontFamily:"ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace",fontSize:"12px",lineHeight:"1.4",color:"#e4e4e7",backgroundColor:"#18181b",border:"1px solid #3f3f46",borderRadius:"6px",padding:"4px 8px",whiteSpace:"nowrap",maxWidth:"500px",overflow:"hidden",textOverflow:"ellipsis",boxShadow:"0 4px 12px rgba(0, 0, 0, 0.4)"},P=(e,t)=>{Object.assign(e.style,t);},p=e=>{let t=e.split("/");return t.length<=3?e:`.../${t.slice(-3).join("/")}`},u=(e,t)=>{let n=document.createElement("span");return n.textContent=e,Object.assign(n.style,t),n},m=class{highlight=null;tooltip=null;init(){this.highlight||(this.highlight=document.createElement("div"),this.highlight.dataset.reactGrep="highlight",P(this.highlight,V),document.body.appendChild(this.highlight),this.tooltip=document.createElement("div"),this.tooltip.dataset.reactGrep="tooltip",P(this.tooltip,B),document.body.appendChild(this.tooltip));}show(t,n,i="source"){if(!this.highlight||!this.tooltip)return;let o=t.getBoundingClientRect();this.highlight.style.top=`${o.top}px`,this.highlight.style.left=`${o.left}px`,this.highlight.style.width=`${o.width}px`,this.highlight.style.height=`${o.height}px`,this.highlight.style.display="block",this.tooltip.textContent="",this.tooltip.appendChild(u(n.name,{color:c.name,fontWeight:"600"})),n.elementTag!=null&&(this.tooltip.appendChild(u(" > ",{color:c.path})),this.tooltip.appendChild(u(n.elementTag,{color:c.tag,fontWeight:"600"})));let s=n.source?`${n.source.fileName}:${n.source.lineNumber}`:null,l=n.callSite?`${n.callSite.fileName}:${n.callSite.lineNumber}`:null;if(s&&l){let I=i==="source"?c.pathActive:c.pathDim,D=i==="callSite"?c.pathActive:c.pathDim,N=Y?"\u21E7":"Shift",$=p(s),R=p(l);this.tooltip.appendChild(u(` ${i==="callSite"?"(":""}${$}${i==="callSite"?")":""}`,{color:I})),this.tooltip.appendChild(u(` ${N} `,{color:c.hint})),this.tooltip.appendChild(u(`${i==="source"?"(":""}${R}${i==="source"?")":""}`,{color:D}));}else s&&this.tooltip.appendChild(u(` ${p(s)}`,{color:c.path}));let a=this.tooltip.getBoundingClientRect(),r=o.top-a.height-6,f=o.left;r<4&&(r=o.bottom+6),f+a.width>window.innerWidth-4&&(f=window.innerWidth-a.width-4),this.tooltip.style.top=`${r}px`,this.tooltip.style.left=`${Math.max(4,f)}px`,this.tooltip.style.display="block";}showCopied(t){this.tooltip&&(this.tooltip.textContent="",this.tooltip.appendChild(u("Copied!",{color:"#4ade80",fontWeight:"600"})),this.tooltip.appendChild(u(` ${p(t)}`,{color:"#a1a1aa"})),this.tooltip.style.display="block",setTimeout(()=>this.hide(),1500));}hide(){this.highlight&&(this.highlight.style.display="none"),this.tooltip&&(this.tooltip.style.display="none");}destroy(){this.highlight?.remove(),this.tooltip?.remove(),this.highlight=null,this.tooltip=null;}};var C=typeof navigator<"u"&&/Mac|iPhone|iPad/.test(navigator.platform),g=class{overlay=new m;moveGeneration=0;lastTarget=null;lastInfo=null;sourceToggled=false;shiftPressedClean=false;boundHandlers;constructor(){this.boundHandlers={mousemove:this.handleMouseMove.bind(this),click:this.handleClick.bind(this),keydown:this.handleKeyDown.bind(this),keyup:this.handleKeyUp.bind(this)};}start(){window.addEventListener("mousemove",this.boundHandlers.mousemove),window.addEventListener("click",this.boundHandlers.click,true),window.addEventListener("keydown",this.boundHandlers.keydown),window.addEventListener("keyup",this.boundHandlers.keyup);}stop(){window.removeEventListener("mousemove",this.boundHandlers.mousemove),window.removeEventListener("click",this.boundHandlers.click,true),window.removeEventListener("keydown",this.boundHandlers.keydown),window.removeEventListener("keyup",this.boundHandlers.keyup),this.overlay.destroy(),document.body.style.cursor="",this.lastTarget=null,this.lastInfo=null,this.sourceToggled=false,this.shiftPressedClean=false;}isModifierHeld(t){return C?t.metaKey:t.ctrlKey}async handleMouseMove(t){if(!this.isModifierHeld(t)){this.overlay.hide(),document.body.style.cursor="",this.lastTarget=null,this.lastInfo=null;return}this.overlay.init(),document.body.style.cursor="crosshair";let n=document.elementFromPoint(t.clientX,t.clientY);if(!n||n.closest("[data-react-grep]"))return;n!==this.lastTarget&&(this.sourceToggled=false);let i=++this.moveGeneration,o=await w(n);if(i===this.moveGeneration){if(!o){this.overlay.hide(),this.lastTarget=null,this.lastInfo=null;return}this.lastTarget=n,this.lastInfo=o,this.overlay.show(n,o,this.getActiveSource());}}async handleClick(t){if(!this.isModifierHeld(t)||!t.shiftKey)return;let n=document.elementFromPoint(t.clientX,t.clientY);if(!n||n.closest("[data-react-grep]"))return;t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.shiftPressedClean=false;let i=await w(n);if(!i)return;let o=this.getActiveCopySource(i);if(!o)return;let{fileName:s,lineNumber:l,columnNumber:a}=o,r=a!=null?`${s}:${l}:${a}`:`${s}:${l}`;await this.copyToClipboard(r),this.overlay.showCopied(r);}handleKeyDown(t){t.key==="Shift"&&this.isModifierHeld(t)&&(this.shiftPressedClean=true);}handleKeyUp(t){if(C&&t.key==="Meta"||!C&&t.key==="Control"){this.overlay.hide(),document.body.style.cursor="",this.lastTarget=null,this.lastInfo=null;return}t.key==="Shift"&&this.shiftPressedClean&&this.lastTarget&&this.lastInfo&&this.lastInfo.callSite&&(this.sourceToggled=!this.sourceToggled,this.overlay.show(this.lastTarget,this.lastInfo,this.getActiveSource())),this.shiftPressedClean=false;}getActiveSource(){return this.sourceToggled?"callSite":"source"}getActiveCopySource(t){return this.sourceToggled&&t.callSite?t.callSite:t.source}async copyToClipboard(t){try{await navigator.clipboard.writeText(t);}catch{}}};var h=null,J=()=>{h||(h=new g,h.start());},it=()=>{h&&(h.stop(),h=null);};if(typeof window<"u"){let e=()=>J();document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e):e();}
3
- exports.destroy=it;exports.init=J;return exports;})({});
1
+ var ReactGrep=(function(exports){'use strict';var k=new Map,T="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",P=[];for(let e=0;e<T.length;e++)P[T.charCodeAt(e)]=e;var m=(e,t)=>{let n=0,i=0;for(;t.i<e.length;){let o=P[e.charCodeAt(t.i++)];if(i+=(o&31)<<n,!(o&32))return i&1?-(i>>1):i>>1;n+=5;}return 0},F=e=>{let t=[],n=0,i=0,o=0;for(let r of e.split(";")){let s=[],a=0;if(r){let l={i:0};for(;l.i<r.length;){if(r.charCodeAt(l.i)===44){l.i++;continue}a+=m(r,l),!(l.i>=r.length||r.charCodeAt(l.i)===44)&&(n+=m(r,l),i+=m(r,l),o+=m(r,l),l.i<r.length&&r.charCodeAt(l.i)!==44&&m(r,l),s.push([a,n,i,o]));}}t.push(s);}return t},U=/^data:application\/json[^,]*;base64,([A-Za-z0-9+/=]+)$/,j=(e,t)=>{try{return new URL(e).origin===new URL(t).origin}catch{return false}},I=async(e,t)=>{if(e.startsWith("data:")){let o=U.exec(e);return o?atob(o[1]):null}let n=new URL(e,t).href;if(!j(t,n))return null;let i=await fetch(n);return i.ok?i.text():null},K=e=>{let t=[],n=[];for(let i of e){let o=F(i.map.mappings),r=i.offset.line,s=i.offset.column,a=t.length;for(;n.length<r+o.length;)n.push([]);for(let l=0;l<o.length;l++){let d=n[r+l];for(let h of o[l])d.push([l===0?h[0]+s:h[0],h[1]+a,h[2],h[3]]);}t.push(...i.map.sources);}for(let i of n)i.length>1&&i.sort((o,r)=>o[0]-r[0]);return {sources:t,mappings:n}},g=e=>{try{let t=JSON.parse(e);return Array.isArray(t.sections)?K(t.sections):!t.sources||!t.mappings?null:{sources:t.sources,mappings:F(t.mappings)}}catch{return null}},W=async e=>{try{let t=await fetch(e),i=(await t.text()).match(/\/\/[#@]\s*sourceMappingURL=([^\s]+)$/m);if(i){let s=await I(i[1].trim(),e);if(s){let a=g(s);if(a)return a}}let o=t.headers.get("SourceMap")??t.headers.get("X-SourceMap");if(o){let s=await I(o.trim(),e);if(s){let a=g(s);if(a)return a}}let r=await fetch(`${e}.map`);if(r.ok){let s=await r.text();return g(s)}return null}catch{return null}},R=/^about:\/\/React\/Server\/file:\/\/\//,G=/[/\\](\.next[/\\].+?)(?:\?.*)?$/,X=async e=>{try{let t=decodeURIComponent(e.replace(R,"")),n=G.exec(t);if(!n)return null;let o=`${typeof location<"u"?location.origin:""}/__nextjs_source-map?filename=${encodeURIComponent(n[1])}`,r=await fetch(o);if(!r.ok)return null;let s=await r.text();return s?g(s):null}catch{return null}},z=e=>{let t=k.get(e);return t||(t=R.test(e)?X(e):W(e),k.set(e,t)),t},V=(e,t,n)=>{if(t<0||t>=e.mappings.length)return null;let i=e.mappings[t];if(!i.length)return null;let o=0,r=i.length-1;for(;o<r;){let s=o+r+1>>1;i[s][0]<=n?o=s:r=s-1;}return i[o]},D=async(e,t,n)=>{let i=await z(e);if(!i)return null;let o=V(i,t-1,n-1);if(!o)return null;let r=i.sources[o[1]];return r.startsWith("file:///")&&(r=decodeURIComponent(new URL(r).pathname)),{fileName:r,lineNumber:o[2]+1,columnNumber:o[3]+1}};var S=e=>"env"in e&&typeof e.name=="string",w=new Set([0,1,11,14,15]),Y=e=>{try{let t=Object.keys(e).find(n=>n.startsWith("__reactFiber$"));return t?e[t]:null}catch{return null}},B=e=>{let t=e;for(;t;){if(w.has(t.tag))return t;t=t.return;}return null},J=e=>{if(typeof e=="function")return e;if(e&&typeof e=="object"){if("render"in e&&typeof e.render=="function")return e.render;if("type"in e&&typeof e.type=="function")return e.type}return null},v=e=>{let{type:t}=e;if(typeof t=="function")return t.displayName||t.name||"Anonymous";if(t&&typeof t=="object"){if("displayName"in t&&t.displayName)return t.displayName;let n=J(t);if(n)return n.displayName||n.name||"Anonymous"}return "Anonymous"},Q=new Set(["jsxDEV","jsxs","jsx","react-stack-top-frame","react_stack_bottom_frame","fakeJSXCallSite"]),q=/at (?:(\S+) )?\(?(.+):(\d+):(\d+)\)?$/,C=e=>{let t=e._debugStack?.stack;if(!t)return null;for(let n of t.split(`
2
+ `)){let i=q.exec(n.trim());if(!i)continue;let[,o,r,s,a]=i;if(!(o&&Q.has(o))&&!r.includes("/node_modules/"))return {url:r,line:Number(s),column:Number(a)}}return null},x=async e=>{let t=await D(e.url,e.line,e.column);if(t)return t;let n=e.url;try{let i=new URL(e.url);n=decodeURIComponent(i.pathname);let o=n.indexOf("?");o!==-1&&(n=n.substring(0,o));}catch{}return n=n.replace(/\.\.\//g,""),n.startsWith("/")&&(n=n.substring(1)),{fileName:n,lineNumber:e.line,columnNumber:e.column}},_=async e=>{if(e._debugSource)return e._debugSource;if(e._debugOwner?._debugSource)return e._debugOwner._debugSource;let t=C(e);if(t)return x(t);if(e._debugOwner){let n=C(e._debugOwner);if(n)return x(n)}return null},$=async e=>{if(e._debugSource)return e._debugSource;let t=C(e);return t?x(t):null},M=async e=>{let t=Y(e);if(!t)return null;let n=B(t);if(!n)return null;if(t.return!=null&&w.has(t.return.tag))return {kind:"component",name:v(n),elementTag:null,source:await _(n),callSite:null};let o=t._debugOwner,r=typeof t.type=="string"?t.type:null;return o&&!S(o)&&o===n?{kind:"element",name:v(o),elementTag:r,source:await $(t),callSite:await _(n)}:{kind:"children",name:o&&S(o)?o.name:v(o&&!S(o)&&w.has(o.tag)?o:n),elementTag:r,source:await $(t),callSite:null}};var Z=typeof navigator<"u"&&/Mac|iPhone|iPad/.test(navigator.platform),c={name:"#93c5fd",tag:"#a78bfa",path:"#71717a",pathActive:"#a1a1aa",pathDim:"#3f3f46",hint:"#52525b"},tt={position:"fixed",pointerEvents:"none",zIndex:"2147483646",backgroundColor:"rgba(66, 135, 245, 0.15)",border:"1.5px solid rgba(66, 135, 245, 0.6)",borderRadius:"3px",display:"none",transition:"top 60ms ease-out, left 60ms ease-out, width 60ms ease-out, height 60ms ease-out"},et={position:"fixed",pointerEvents:"none",zIndex:"2147483647",display:"none",fontFamily:"ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace",fontSize:"12px",lineHeight:"1.4",color:"#e4e4e7",backgroundColor:"#18181b",border:"1px solid #3f3f46",borderRadius:"6px",padding:"4px 8px",whiteSpace:"nowrap",maxWidth:"500px",overflow:"hidden",textOverflow:"ellipsis",boxShadow:"0 4px 12px rgba(0, 0, 0, 0.4)"},N=(e,t)=>{Object.assign(e.style,t);},f=e=>{let t=e.split("/");return t.length<=2?e:`.../${t.slice(-2).join("/")}`},u=(e,t)=>{let n=document.createElement("span");return n.textContent=e,Object.assign(n.style,t),n},y=class{highlight=null;tooltip=null;init(){this.highlight||(this.highlight=document.createElement("div"),this.highlight.dataset.reactGrep="highlight",N(this.highlight,tt),document.body.appendChild(this.highlight),this.tooltip=document.createElement("div"),this.tooltip.dataset.reactGrep="tooltip",N(this.tooltip,et),document.body.appendChild(this.tooltip));}show(t,n,i="source"){if(!this.highlight||!this.tooltip)return;let o=t.getBoundingClientRect();this.highlight.style.top=`${o.top}px`,this.highlight.style.left=`${o.left}px`,this.highlight.style.width=`${o.width}px`,this.highlight.style.height=`${o.height}px`,this.highlight.style.display="block",this.tooltip.textContent="",this.tooltip.appendChild(u(n.name,{color:c.name,fontWeight:"600"})),n.elementTag!=null&&(this.tooltip.appendChild(u(" > ",{color:c.path})),this.tooltip.appendChild(u(n.elementTag,{color:c.tag,fontWeight:"600"})));let r=n.source?`${n.source.fileName}:${n.source.lineNumber}`:null,s=n.callSite?`${n.callSite.fileName}:${n.callSite.lineNumber}`:null;if(r&&s){let h=i==="source"?c.pathActive:c.pathDim,O=i==="callSite"?c.pathActive:c.pathDim,A=Z?"\u21E7":"Shift",L=f(r),H=f(s);this.tooltip.appendChild(u(` ${i==="callSite"?"(":""}${L}${i==="callSite"?")":""}`,{color:h})),this.tooltip.appendChild(u(` ${A} `,{color:c.hint})),this.tooltip.appendChild(u(`${i==="source"?"(":""}${H}${i==="source"?")":""}`,{color:O}));}else r&&this.tooltip.appendChild(u(` ${f(r)}`,{color:c.path}));let a=this.tooltip.getBoundingClientRect(),l=o.top-a.height-6,d=o.left;l<4&&(l=o.bottom+6),d+a.width>window.innerWidth-4&&(d=window.innerWidth-a.width-4),this.tooltip.style.top=`${l}px`,this.tooltip.style.left=`${Math.max(4,d)}px`,this.tooltip.style.display="block";}showCopied(t){this.tooltip&&(this.tooltip.textContent="",this.tooltip.appendChild(u("Copied!",{color:"#4ade80",fontWeight:"600"})),this.tooltip.appendChild(u(` ${f(t)}`,{color:"#a1a1aa"})),this.tooltip.style.display="block",setTimeout(()=>this.hide(),1500));}hide(){this.highlight&&(this.highlight.style.display="none"),this.tooltip&&(this.tooltip.style.display="none");}destroy(){this.highlight?.remove(),this.tooltip?.remove(),this.highlight=null,this.tooltip=null;}};var E=typeof navigator<"u"&&/Mac|iPhone|iPad/.test(navigator.platform),b=class{overlay=new y;moveGeneration=0;lastTarget=null;lastInfo=null;sourceToggled=false;shiftPressedClean=false;boundHandlers;constructor(){this.boundHandlers={mousemove:this.handleMouseMove.bind(this),click:this.handleClick.bind(this),keydown:this.handleKeyDown.bind(this),keyup:this.handleKeyUp.bind(this)};}start(){window.addEventListener("mousemove",this.boundHandlers.mousemove),window.addEventListener("click",this.boundHandlers.click,true),window.addEventListener("keydown",this.boundHandlers.keydown),window.addEventListener("keyup",this.boundHandlers.keyup);}stop(){window.removeEventListener("mousemove",this.boundHandlers.mousemove),window.removeEventListener("click",this.boundHandlers.click,true),window.removeEventListener("keydown",this.boundHandlers.keydown),window.removeEventListener("keyup",this.boundHandlers.keyup),this.overlay.destroy(),document.body.style.cursor="",this.lastTarget=null,this.lastInfo=null,this.sourceToggled=false,this.shiftPressedClean=false;}isModifierHeld(t){return E?t.metaKey:t.ctrlKey}async handleMouseMove(t){if(!this.isModifierHeld(t)){this.overlay.hide(),document.body.style.cursor="",this.lastTarget=null,this.lastInfo=null;return}this.overlay.init(),document.body.style.cursor="crosshair";let n=document.elementFromPoint(t.clientX,t.clientY);if(!n||n.closest("[data-react-grep]"))return;n!==this.lastTarget&&(this.sourceToggled=false);let i=++this.moveGeneration,o=await M(n);if(i===this.moveGeneration){if(!o){this.overlay.hide(),this.lastTarget=null,this.lastInfo=null;return}this.lastTarget=n,this.lastInfo=o,this.overlay.show(n,o,this.getActiveSource());}}async handleClick(t){if(!this.isModifierHeld(t)||!t.shiftKey)return;let n=document.elementFromPoint(t.clientX,t.clientY);if(!n||n.closest("[data-react-grep]"))return;t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation(),this.shiftPressedClean=false;let i=await M(n);if(!i)return;let o=this.getActiveCopySource(i);if(!o)return;let{fileName:r,lineNumber:s,columnNumber:a}=o,l=a!=null?`${r}:${s}:${a}`:`${r}:${s}`;await this.copyToClipboard(l),this.overlay.showCopied(l);}handleKeyDown(t){t.key==="Shift"&&this.isModifierHeld(t)&&(this.shiftPressedClean=true);}handleKeyUp(t){if(E&&t.key==="Meta"||!E&&t.key==="Control"){this.overlay.hide(),document.body.style.cursor="",this.lastTarget=null,this.lastInfo=null;return}t.key==="Shift"&&this.shiftPressedClean&&this.lastTarget&&this.lastInfo&&this.lastInfo.callSite&&(this.sourceToggled=!this.sourceToggled,this.overlay.show(this.lastTarget,this.lastInfo,this.getActiveSource())),this.shiftPressedClean=false;}getActiveSource(){return this.sourceToggled?"callSite":"source"}getActiveCopySource(t){return this.sourceToggled&&t.callSite?t.callSite:t.source}async copyToClipboard(t){try{await navigator.clipboard.writeText(t);}catch{}}};var p=null,nt=()=>{p||(p=new b,p.start());},ht=()=>{p&&(p.stop(),p=null);};if(typeof window<"u"){let e=()=>nt();document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e):e();}
3
+ exports.destroy=ht;exports.init=nt;return exports;})({});
package/dist/index.js CHANGED
@@ -50,26 +50,93 @@ var isSameOrigin = (a, b) => {
50
50
  return false;
51
51
  }
52
52
  };
53
+ var fetchSourceMapJson = async (ref, baseUrl) => {
54
+ if (ref.startsWith("data:")) {
55
+ const dataMatch = DATA_URI_RE.exec(ref);
56
+ return dataMatch ? atob(dataMatch[1]) : null;
57
+ }
58
+ const mapUrl = new URL(ref, baseUrl).href;
59
+ if (!isSameOrigin(baseUrl, mapUrl)) return null;
60
+ const mapRes = await fetch(mapUrl);
61
+ if (!mapRes.ok) return null;
62
+ return mapRes.text();
63
+ };
64
+ var flattenIndexedMap = (sections) => {
65
+ const allSources = [];
66
+ const allMappings = [];
67
+ for (const section of sections) {
68
+ const decoded = decodeMappings(section.map.mappings);
69
+ const lineOff = section.offset.line;
70
+ const colOff = section.offset.column;
71
+ const srcOff = allSources.length;
72
+ while (allMappings.length < lineOff + decoded.length) allMappings.push([]);
73
+ for (let i = 0; i < decoded.length; i++) {
74
+ const target = allMappings[lineOff + i];
75
+ for (const seg of decoded[i]) {
76
+ target.push([i === 0 ? seg[0] + colOff : seg[0], seg[1] + srcOff, seg[2], seg[3]]);
77
+ }
78
+ }
79
+ allSources.push(...section.map.sources);
80
+ }
81
+ for (const line of allMappings) {
82
+ if (line.length > 1) line.sort((a, b) => a[0] - b[0]);
83
+ }
84
+ return { sources: allSources, mappings: allMappings };
85
+ };
86
+ var parseSourceMap = (json) => {
87
+ try {
88
+ const raw = JSON.parse(json);
89
+ if (Array.isArray(raw.sections)) return flattenIndexedMap(raw.sections);
90
+ if (!raw.sources || !raw.mappings) return null;
91
+ return { sources: raw.sources, mappings: decodeMappings(raw.mappings) };
92
+ } catch {
93
+ return null;
94
+ }
95
+ };
53
96
  var fetchAndParse = async (url) => {
54
97
  try {
55
98
  const res = await fetch(url);
56
99
  const text = await res.text();
57
100
  const match = text.match(/\/\/[#@]\s*sourceMappingURL=([^\s]+)$/m);
58
- if (!match) return null;
59
- const ref = match[1].trim();
60
- let mapJson;
61
- if (ref.startsWith("data:")) {
62
- const dataMatch = DATA_URI_RE.exec(ref);
63
- if (!dataMatch) return null;
64
- mapJson = atob(dataMatch[1]);
65
- } else {
66
- const mapUrl = new URL(ref, url).href;
67
- if (!isSameOrigin(url, mapUrl)) return null;
68
- const mapRes = await fetch(mapUrl);
69
- mapJson = await mapRes.text();
101
+ if (match) {
102
+ const json = await fetchSourceMapJson(match[1].trim(), url);
103
+ if (json) {
104
+ const map = parseSourceMap(json);
105
+ if (map) return map;
106
+ }
70
107
  }
71
- const raw = JSON.parse(mapJson);
72
- return { sources: raw.sources, mappings: decodeMappings(raw.mappings) };
108
+ const headerRef = res.headers.get("SourceMap") ?? res.headers.get("X-SourceMap");
109
+ if (headerRef) {
110
+ const json = await fetchSourceMapJson(headerRef.trim(), url);
111
+ if (json) {
112
+ const map = parseSourceMap(json);
113
+ if (map) return map;
114
+ }
115
+ }
116
+ const conventionRes = await fetch(`${url}.map`);
117
+ if (conventionRes.ok) {
118
+ const json = await conventionRes.text();
119
+ return parseSourceMap(json);
120
+ }
121
+ return null;
122
+ } catch {
123
+ return null;
124
+ }
125
+ };
126
+ var ABOUT_SERVER_RE = /^about:\/\/React\/Server\/file:\/\/\//;
127
+ var NEXT_DOTDIR_RE = /[/\\](\.next[/\\].+?)(?:\?.*)?$/;
128
+ var fetchAndParseServerFile = async (url) => {
129
+ try {
130
+ const filePath = decodeURIComponent(url.replace(ABOUT_SERVER_RE, ""));
131
+ const dotNextMatch = NEXT_DOTDIR_RE.exec(filePath);
132
+ if (!dotNextMatch) return null;
133
+ const origin = typeof location !== "undefined" ? location.origin : "";
134
+ const mapUrl = `${origin}/__nextjs_source-map?filename=${encodeURIComponent(dotNextMatch[1])}`;
135
+ const res = await fetch(mapUrl);
136
+ if (!res.ok) return null;
137
+ const json = await res.text();
138
+ if (!json) return null;
139
+ return parseSourceMap(json);
73
140
  } catch {
74
141
  return null;
75
142
  }
@@ -77,7 +144,7 @@ var fetchAndParse = async (url) => {
77
144
  var getSourceMap = (url) => {
78
145
  let promise = cache.get(url);
79
146
  if (!promise) {
80
- promise = fetchAndParse(url);
147
+ promise = ABOUT_SERVER_RE.test(url) ? fetchAndParseServerFile(url) : fetchAndParse(url);
81
148
  cache.set(url, promise);
82
149
  }
83
150
  return promise;
@@ -100,7 +167,10 @@ var resolveOriginalPosition = async (url, line, column) => {
100
167
  if (!map) return null;
101
168
  const seg = lookup(map, line - 1, column - 1);
102
169
  if (!seg) return null;
103
- const fileName = map.sources[seg[1]];
170
+ let fileName = map.sources[seg[1]];
171
+ if (fileName.startsWith("file:///")) {
172
+ fileName = decodeURIComponent(new URL(fileName).pathname);
173
+ }
104
174
  return {
105
175
  fileName,
106
176
  lineNumber: seg[2] + 1,
@@ -109,6 +179,7 @@ var resolveOriginalPosition = async (url, line, column) => {
109
179
  };
110
180
 
111
181
  // src/fiber.ts
182
+ var isServerComponent = (owner) => "env" in owner && typeof owner.name === "string";
112
183
  var COMPOSITE_TAGS = /* @__PURE__ */ new Set([
113
184
  0,
114
185
  // FunctionComponent
@@ -165,7 +236,8 @@ var SKIP_FRAMES = /* @__PURE__ */ new Set([
165
236
  "jsxs",
166
237
  "jsx",
167
238
  "react-stack-top-frame",
168
- "react_stack_bottom_frame"
239
+ "react_stack_bottom_frame",
240
+ "fakeJSXCallSite"
169
241
  ]);
170
242
  var FRAME_RE = /at (?:(\S+) )?\(?(.+):(\d+):(\d+)\)?$/;
171
243
  var parseFirstUserFrame = (fiber) => {
@@ -230,7 +302,7 @@ var getComponentInfo = async (el) => {
230
302
  }
231
303
  const owner = domFiber._debugOwner;
232
304
  const elementTag = typeof domFiber.type === "string" ? domFiber.type : null;
233
- if (owner && owner === composite) {
305
+ if (owner && !isServerComponent(owner) && owner === composite) {
234
306
  return {
235
307
  kind: "element",
236
308
  name: getComponentName(owner),
@@ -239,10 +311,12 @@ var getComponentInfo = async (el) => {
239
311
  callSite: await getCompositeDebugSource(composite)
240
312
  };
241
313
  }
242
- const nameSource = owner && COMPOSITE_TAGS.has(owner.tag) ? owner : composite;
314
+ const name = owner && isServerComponent(owner) ? owner.name : getComponentName(
315
+ owner && !isServerComponent(owner) && COMPOSITE_TAGS.has(owner.tag) ? owner : composite
316
+ );
243
317
  return {
244
318
  kind: "children",
245
- name: getComponentName(nameSource),
319
+ name,
246
320
  elementTag,
247
321
  source: await getDomDebugSource(domFiber),
248
322
  callSite: null
@@ -293,8 +367,8 @@ var applyStyles = (el, styles) => {
293
367
  };
294
368
  var truncatePath = (filePath) => {
295
369
  const parts = filePath.split("/");
296
- if (parts.length <= 3) return filePath;
297
- return `.../${parts.slice(-3).join("/")}`;
370
+ if (parts.length <= 2) return filePath;
371
+ return `.../${parts.slice(-2).join("/")}`;
298
372
  };
299
373
  var createSpan = (text, styles) => {
300
374
  const span = document.createElement("span");
@@ -369,11 +443,11 @@ var OverlayManager = class {
369
443
  this.tooltip.style.left = `${Math.max(4, left)}px`;
370
444
  this.tooltip.style.display = "block";
371
445
  }
372
- showCopied(location) {
446
+ showCopied(location2) {
373
447
  if (!this.tooltip) return;
374
448
  this.tooltip.textContent = "";
375
449
  this.tooltip.appendChild(createSpan("Copied!", { color: "#4ade80", fontWeight: "600" }));
376
- this.tooltip.appendChild(createSpan(` ${truncatePath(location)}`, { color: "#a1a1aa" }));
450
+ this.tooltip.appendChild(createSpan(` ${truncatePath(location2)}`, { color: "#a1a1aa" }));
377
451
  this.tooltip.style.display = "block";
378
452
  setTimeout(() => this.hide(), 1500);
379
453
  }
@@ -469,9 +543,9 @@ var Inspector = class {
469
543
  const source = this.getActiveCopySource(info);
470
544
  if (!source) return;
471
545
  const { fileName, lineNumber, columnNumber } = source;
472
- const location = columnNumber != null ? `${fileName}:${lineNumber}:${columnNumber}` : `${fileName}:${lineNumber}`;
473
- await this.copyToClipboard(location);
474
- this.overlay.showCopied(location);
546
+ const location2 = columnNumber != null ? `${fileName}:${lineNumber}:${columnNumber}` : `${fileName}:${lineNumber}`;
547
+ await this.copyToClipboard(location2);
548
+ this.overlay.showCopied(location2);
475
549
  }
476
550
  handleKeyDown(e) {
477
551
  if (e.key === "Shift" && this.isModifierHeld(e)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-grep",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Hold CMD to see React component names + file:line overlaid on any element",
5
5
  "keywords": [
6
6
  "component",