ugly-app 0.1.714 → 0.1.716
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/cli/version.d.ts +1 -1
- package/dist/cli/version.js +1 -1
- package/dist/inspect/agent/bundle-entry.d.ts +2 -0
- package/dist/inspect/agent/bundle-entry.d.ts.map +1 -0
- package/dist/inspect/agent/bundle-entry.js +7 -0
- package/dist/inspect/agent/bundle-entry.js.map +1 -0
- package/dist/inspect/agent-bundle.js +3 -0
- package/dist/inspect/ui/InspectPanel.d.ts +8 -0
- package/dist/inspect/ui/InspectPanel.d.ts.map +1 -0
- package/dist/inspect/ui/InspectPanel.js +79 -0
- package/dist/inspect/ui/InspectPanel.js.map +1 -0
- package/dist/inspect/ui/InspectPanel.test.d.ts +2 -0
- package/dist/inspect/ui/InspectPanel.test.d.ts.map +1 -0
- package/dist/inspect/ui/InspectPanel.test.js +77 -0
- package/dist/inspect/ui/InspectPanel.test.js.map +1 -0
- package/dist/inspect/ui/RemoteValueView.d.ts +10 -0
- package/dist/inspect/ui/RemoteValueView.d.ts.map +1 -0
- package/dist/inspect/ui/RemoteValueView.js +74 -0
- package/dist/inspect/ui/RemoteValueView.js.map +1 -0
- package/dist/inspect/ui/index.d.ts +4 -0
- package/dist/inspect/ui/index.d.ts.map +1 -0
- package/dist/inspect/ui/index.js +6 -0
- package/dist/inspect/ui/index.js.map +1 -0
- package/dist/inspect/ui/panels/ConsolePanel.d.ts +6 -0
- package/dist/inspect/ui/panels/ConsolePanel.d.ts.map +1 -0
- package/dist/inspect/ui/panels/ConsolePanel.js +55 -0
- package/dist/inspect/ui/panels/ConsolePanel.js.map +1 -0
- package/dist/inspect/ui/panels/ElementsPanel.d.ts +6 -0
- package/dist/inspect/ui/panels/ElementsPanel.d.ts.map +1 -0
- package/dist/inspect/ui/panels/ElementsPanel.js +84 -0
- package/dist/inspect/ui/panels/ElementsPanel.js.map +1 -0
- package/dist/inspect/ui/panels/NetworkPanel.d.ts +6 -0
- package/dist/inspect/ui/panels/NetworkPanel.d.ts.map +1 -0
- package/dist/inspect/ui/panels/NetworkPanel.js +73 -0
- package/dist/inspect/ui/panels/NetworkPanel.js.map +1 -0
- package/dist/inspect/ui/panels/PerformancePanel.d.ts +6 -0
- package/dist/inspect/ui/panels/PerformancePanel.d.ts.map +1 -0
- package/dist/inspect/ui/panels/PerformancePanel.js +54 -0
- package/dist/inspect/ui/panels/PerformancePanel.js.map +1 -0
- package/dist/inspect/ui/panels/StoragePanel.d.ts +6 -0
- package/dist/inspect/ui/panels/StoragePanel.d.ts.map +1 -0
- package/dist/inspect/ui/panels/StoragePanel.js +20 -0
- package/dist/inspect/ui/panels/StoragePanel.js.map +1 -0
- package/dist/inspect/ui/styles.d.ts +4 -0
- package/dist/inspect/ui/styles.d.ts.map +1 -0
- package/dist/inspect/ui/styles.js +230 -0
- package/dist/inspect/ui/styles.js.map +1 -0
- package/package.json +5 -3
- package/src/cli/version.ts +1 -1
- package/src/inspect/agent/bundle-entry.ts +8 -0
- package/src/inspect/ui/InspectPanel.test.tsx +90 -0
- package/src/inspect/ui/InspectPanel.tsx +163 -0
- package/src/inspect/ui/RemoteValueView.tsx +108 -0
- package/src/inspect/ui/index.ts +6 -0
- package/src/inspect/ui/panels/ConsolePanel.tsx +111 -0
- package/src/inspect/ui/panels/ElementsPanel.tsx +244 -0
- package/src/inspect/ui/panels/NetworkPanel.tsx +149 -0
- package/src/inspect/ui/panels/PerformancePanel.tsx +118 -0
- package/src/inspect/ui/panels/StoragePanel.tsx +101 -0
- package/src/inspect/ui/styles.ts +232 -0
package/dist/cli/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const CLI_VERSION = "0.1.
|
|
1
|
+
export declare const CLI_VERSION = "0.1.716";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/cli/version.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle-entry.d.ts","sourceRoot":"","sources":["../../../src/inspect/agent/bundle-entry.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Entry for the pre-bundled, injectable agent IIFE. The ugly-app build esbuilds
|
|
2
|
+
// this into dist/inspect/agent-bundle.js (a single self-contained script with no
|
|
3
|
+
// imports), which native shells read as text and inject at document-start —
|
|
4
|
+
// no runtime bundler needed on the host side.
|
|
5
|
+
import { installInspectAgent } from './install.js';
|
|
6
|
+
installInspectAgent();
|
|
7
|
+
//# sourceMappingURL=bundle-entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle-entry.js","sourceRoot":"","sources":["../../../src/inspect/agent/bundle-entry.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,iFAAiF;AACjF,4EAA4E;AAC5E,8CAA8C;AAE9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,mBAAmB,EAAE,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";(()=>{var w=class{constructor(t){this.cap=t}cap;items=[];push(t){this.items.push(t),this.items.length>this.cap&&this.items.splice(0,this.items.length-this.cap)}since(t,n){let r=0,o=this.items.length;for(;r<o;){let s=r+o>>>1;n(this.items[s])<t?r=s+1:o=s}return this.items.slice(r)}all(){return this.items.slice()}clear(){this.items=[]}size(){return this.items.length}};var b=class{seq=0;byId=new Map;put(t){let n=`o${++this.seq}`;return this.byId.set(n,t),n}get(t){return this.byId.get(t)}clear(){this.byId.clear()}};function ie(e){return typeof Node<"u"&&typeof e=="object"&&e!==null&&e instanceof Node}function E(e,t){return e.length>t?`${e.slice(0,t)}\u2026`:e}function x(e){return Object.getPrototypeOf(e)?.constructor?.name}function p(e,t){switch(typeof e){case"undefined":return{type:"undefined"};case"boolean":return{type:"boolean",value:e};case"bigint":return{type:"bigint",value:`${e}n`,preview:`${e}n`};case"symbol":return{type:"symbol",value:String(e),preview:String(e)};case"string":return{type:"string",value:E(e,1e3)};case"number":return Number.isFinite(e)?{type:"number",value:e}:{type:"number",value:String(e),preview:String(e)};case"function":return{type:"function",className:"Function",preview:`\u0192 ${e.name||"(anonymous)"}()`};case"object":break;default:return{type:"object",preview:String(e)}}if(e===null)return{type:"null"};let n=e;if(ie(e))return{type:"node",className:e.nodeName??"Node",preview:ce(e),nodeId:t.nodeIdFor?.(e)};if(e instanceof Date)return{type:"date",className:"Date",preview:le(e)};if(e instanceof RegExp)return{type:"regexp",className:"RegExp",preview:String(e)};if(e instanceof Error)return{type:"error",className:e.name||"Error",preview:E(`${e.name}: ${e.message}`,100),objectId:t.registry.put(e)};if(ue(e))return{type:"promise",className:"Promise",preview:"Promise",objectId:t.registry.put(e)};if(e instanceof Map)return{type:"map",className:"Map",size:e.size,objectId:t.registry.put(e),preview:`Map(${e.size})`,entries:C(e,t)};if(e instanceof Set)return{type:"set",className:"Set",size:e.size,objectId:t.registry.put(e),preview:`Set(${e.size})`,entries:D(e,t)};if(Array.isArray(e))return{type:"array",className:"Array",size:e.length,objectId:t.registry.put(e),preview:`Array(${e.length})`,entries:L(e,t)};let r=Object.keys(n);return{type:"object",className:x(n)??"Object",size:r.length,objectId:t.registry.put(n),preview:se(n,r),entries:v(n,r,t)}}function P(e,t){if(e instanceof Map)return C(e,t,1/0).map(n=>n.value);if(e instanceof Set)return D(e,t,1/0).map(n=>n.value);if(Array.isArray(e))return L(e,t,1/0).map(n=>n.value);if(e instanceof Error)return v({name:e.name,message:e.message,stack:e.stack},["name","message","stack"],t,1/0).map(n=>n.value);if(typeof e=="object"&&e!==null){let n=Object.keys(e);return v(e,n,t,1/0).map(r=>r.value)}return[]}function L(e,t,n=5){let r=[];for(let o=0;o<e.length&&o<n;o++)r.push({key:String(o),value:p(e[o],t)});return r}function v(e,t,n,r=5){let o=[];for(let s=0;s<t.length&&s<r;s++){let i=t[s],c;try{c=e[i]}catch{c="(getter threw)"}o.push({key:i,value:p(c,n)})}return o}function C(e,t,n=5){let r=[],o=0;for(let[s,i]of e){if(o++>=n)break;r.push({key:p(s,t),value:p(i,t)})}return r}function D(e,t,n=5){let r=[],o=0;for(let s of e){if(o++>=n)break;r.push({value:p(s,t)})}return r}function se(e,t){let n=t.slice(0,5).map(o=>{let s;try{s=e[o]}catch{s="\u2026"}return`${o}: ${ae(s)}`}),r=t.length>5?", \u2026":"";return E(`{${n.join(", ")}${r}}`,100)}function ae(e){let t=typeof e;return t==="string"?`"${E(e,20)}"`:t==="object"&&e!==null?Array.isArray(e)?`Array(${e.length})`:x(e)??"Object":String(e)}function ce(e){let t=e;if(t.nodeType===1){let n=(t.nodeName??"").toLowerCase(),r=t.id?`#${t.id}`:"",o=typeof t.className=="string"&&t.className?`.${t.className.trim().split(/\s+/).join(".")}`:"";return E(`<${n}${r}${o}>`,100)}return t.nodeName??"Node"}function ue(e){return typeof e?.then=="function"}function le(e){try{return e.toISOString()}catch{return"Invalid Date"}}var _=["log","info","warn","error","debug"];function j(e){if(typeof console>"u")return()=>{};let t=0,n={};for(let i of _){let c=console[i];typeof c=="function"&&(n[i]=c,console[i]=(...l)=>{try{s(i,l)}catch{}c.apply(console,l)})}let r=i=>{s("error",[i.message],{stack:y(i.error?.stack),source:{url:i.filename||"",line:i.lineno||0,col:i.colno||0}})},o=i=>{let c=i.reason;s("error",[`Unhandled rejection: ${c?.message??String(i.reason)}`],{stack:y(c?.stack)})};typeof window<"u"&&(window.addEventListener("error",r),window.addEventListener("unhandledrejection",o));function s(i,c,l){let f=c.map(g=>p(g,{registry:e.registry,nodeIdFor:e.nodeIdFor})),a=l?.stack??y(new Error().stack,1),d={seq:++t,ts:e.now(),level:i,args:f,text:de(c),stack:a.length?a:void 0,source:l?.source??a[0]?{url:a[0].url,line:a[0].line,col:a[0].col}:void 0};e.buffer.push(d),e.onEntry?.(d)}return()=>{for(let i of _){let c=n[i];c&&(console[i]=c)}typeof window<"u"&&(window.removeEventListener("error",r),window.removeEventListener("unhandledrejection",o))}}function de(e){return e.map(t=>{if(typeof t=="string")return t;if(t instanceof Error)return`${t.name}: ${t.message}`;try{return JSON.stringify(t)}catch{return String(t)}}).join(" ").slice(0,2e3)}function y(e,t=0){if(!e)return[];let n=[],r=e.split(`
|
|
2
|
+
`);for(let o of r){let s=o.trim(),i=/^at\s+(.*?)\s+\((.*?):(\d+):(\d+)\)$/.exec(s)||/^at\s+(.*?):(\d+):(\d+)$/.exec(s);if(i){i.length===5?n.push({functionName:i[1],url:i[2],line:+i[3],col:+i[4]}):n.push({functionName:"(anonymous)",url:i[1],line:+i[2],col:+i[3]});continue}i=/^(.*?)@(.*?):(\d+):(\d+)$/.exec(s),i&&n.push({functionName:i[1]||"(anonymous)",url:i[2],line:+i[3],col:+i[4]})}return n.slice(t)}function $(e,t=40,n=Date.now){let r=typeof document<"u"&&document.documentElement?M(document.documentElement,e,t,0):ge();return{documentUrl:typeof location<"u"?location.href:"",capturedAt:n(),root:r}}function M(e,t,n,r){let o={nodeId:t.idFor(e),nodeType:e.nodeType,nodeName:e.nodeName};if(e.nodeType===Node.TEXT_NODE||e.nodeType===Node.COMMENT_NODE){let a=(e.textContent??"").trim();return a&&(o.textContent=a.slice(0,200)),o}if(e.nodeType!==Node.ELEMENT_NODE)return o;let s=e;if(o.attributes=me(s),o.rect=pe(s),r>=n)return o;let i=s.shadowRoot;i&&(o.shadowRoots=Array.from(i.childNodes).filter(O).map(a=>M(a,t,n,r+1)));let c=[],l=A(s,"before");l&&c.push(l);for(let a of Array.from(s.childNodes))O(a)&&c.push(M(a,t,n,r+1));let f=A(s,"after");return f&&c.push(f),c.length&&(o.children=c),o}function A(e,t){if(typeof getComputedStyle>"u")return;let n;try{n=getComputedStyle(e,`::${t}`).content}catch{return}if(!(!n||n==="none"||n==="normal"))return{nodeId:`${fe(e)}::${t}`,nodeType:1,nodeName:`::${t}`,pseudo:t,textContent:n}}function fe(e){return e.__inspectPseudoBase??e.tagName}function O(e){return e.nodeType===Node.TEXT_NODE?!!(e.textContent??"").trim():e.nodeType===Node.ELEMENT_NODE||e.nodeType===Node.COMMENT_NODE}function me(e){let t={};for(let n of Array.from(e.attributes))t[n.name]=n.value;return t}function pe(e){let t=e.getBoundingClientRect();return{x:t.x,y:t.y,w:t.width,h:t.height}}function ge(){return{nodeId:"n0",nodeType:9,nodeName:"#document"}}function B(e,t){let n=ye(e,t);if(!n)throw new Error(`inspect.element: node not found (${t.nodeId??t.selector??"?"})`);let r=getComputedStyle(n),o=Se(n);return{nodeId:e.idFor(n),tag:n.tagName.toLowerCase(),attributes:Re(n),computedStyles:he(r),matchedRules:we(n),boxModel:be(n,r,o),eventListeners:ke(n),accessibility:Ne(n),rect:o}}function ye(e,t){if(t.nodeId){let n=e.get(t.nodeId);return n?.nodeType===1?n:null}return t.selector&&typeof document<"u"?document.querySelector(t.selector):null}function he(e){let t={};for(let n=0;n<e.length;n++){let r=e.item(n);t[r]=e.getPropertyValue(r)}return t}function we(e){let t=[];if(typeof document>"u")return t;for(let n of Array.from(document.styleSheets)){let r;try{r=n.cssRules}catch{continue}let o=n.href??void 0;for(let s of Array.from(r)){if(!(s instanceof CSSStyleRule))continue;let i=!1;try{i=e.matches(s.selectorText)}catch{i=!1}i&&t.push({selector:s.selectorText,source:o?{url:o,line:0,col:0}:void 0,props:Ee(s.style)})}}return t}function Ee(e){let t={};for(let n=0;n<e.length;n++){let r=e.item(n);t[r]=e.getPropertyValue(r)}return t}function be(e,t,n){let r=(o,s)=>({top:k(t.getPropertyValue(`${o}-top${s}`)),right:k(t.getPropertyValue(`${o}-right${s}`)),bottom:k(t.getPropertyValue(`${o}-bottom${s}`)),left:k(t.getPropertyValue(`${o}-left${s}`))});return{content:n,padding:r("padding",""),border:r("border","-width"),margin:r("margin","")}}function ke(e){let n=(typeof window<"u"?window:{}).__inspectGetEventListeners;if(!n)return[];try{let r=n(e),o=[];for(let[s,i]of Object.entries(r))for(let c of i)o.push({type:s,useCapture:c.useCapture,passive:c.passive});return o}catch{return[]}}function Ne(e){let t={};for(let o of Array.from(e.attributes))o.name.startsWith("aria-")&&(t[o.name]=o.value);let n=e.getAttribute("role")??void 0,r=e.getAttribute("aria-label")??e.title??(e.textContent??"").trim().slice(0,80)??void 0;return{role:n,name:r||void 0,properties:t}}function Re(e){let t={};for(let n of Array.from(e.attributes))t[n.name]=n.value;return t}function Se(e){let t=e.getBoundingClientRect();return{x:t.x,y:t.y,w:t.width,h:t.height}}function k(e){let t=parseFloat(e);return Number.isFinite(t)?t:0}async function V(e,t,n){let r=t.now();try{let o=ve(e,n?.replMode?{$0:t.getPicked(),$_:t.getLast()}:{});return n?.awaitPromise&&Me(o)&&(o=await o),t.setLast(o),{ok:!0,value:p(o,{registry:t.registry,nodeIdFor:t.nodeIdFor}),tookMs:t.now()-r}}catch(o){let s=o;return{ok:!1,exception:{text:`${s?.name??"Error"}: ${s?.message??String(o)}`,stack:y(s?.stack)},tookMs:t.now()-r}}}function ve(e,t){let n=Object.keys(t);if(n.length===0)return(0,eval)(e);let r=new Function(...n,`return (${e});`);try{return r(...n.map(o=>t[o]))}catch(o){if(o instanceof SyntaxError)return new Function(...n,e)(...n.map(i=>t[i]));throw o}}function Me(e){return typeof e?.then=="function"}var N=64*1024;function H(e){if(typeof window>"u")return()=>{};let t=0,n=()=>`r${++t}`,r=window.fetch?.bind(window);r&&(window.fetch=async(l,f)=>{let a=e.now(),d=(f?.method||(l instanceof Request?l.method:"GET")).toUpperCase(),g=l instanceof Request?l.url:String(l),u={id:n(),ts:a,method:d,url:g,resourceType:"fetch",requestHeaders:F(f?.headers??(l instanceof Request?l.headers:void 0)),requestBody:X(f?.body),timing:{startMs:a,durationMs:0}};try{let m=await r(l,f);return u.status=m.status,u.responseHeaders=F(m.headers),u.timing.durationMs=e.now()-a,u.fromCache=m.fromCache,await Te(m,u),c(u),m}catch(m){throw u.failed=!0,u.timing.durationMs=e.now()-a,u.responseBody={kind:"text",data:String(m?.message??m)},c(u),m}});let o=window.XMLHttpRequest,s=o?.prototype.open,i=o?.prototype.send;o&&s&&i&&(o.prototype.open=function(f,a,...d){return this.__inspect={method:f.toUpperCase(),url:a,start:0},s.apply(this,[f,a,...d])},o.prototype.send=function(f){let a=this.__inspect;return a&&(a.start=e.now(),this.addEventListener("loadend",()=>{let d={id:n(),ts:a.start,method:a.method,url:a.url,status:this.status,resourceType:"xhr",requestHeaders:{},responseHeaders:Ie(this.getAllResponseHeaders()),requestBody:X(f),responseBody:xe(this),timing:{startMs:a.start,durationMs:e.now()-a.start},failed:this.status===0};c(d)})),i.apply(this,[f])});function c(l){e.buffer.push(l),e.onEntry?.(l)}return()=>{r&&(window.fetch=r),o&&s&&(o.prototype.open=s),o&&i&&(o.prototype.send=i)}}function F(e){let t={};if(!e)return t;if(typeof Headers<"u"&&e instanceof Headers)e.forEach((n,r)=>t[r]=n);else if(Array.isArray(e))for(let[n,r]of e)t[n]=r;else Object.assign(t,e);return t}function Ie(e){let t={};for(let n of e.split(`\r
|
|
3
|
+
`)){let r=n.indexOf(":");r>0&&(t[n.slice(0,r).trim().toLowerCase()]=n.slice(r+1).trim())}return t}function X(e){if(e!=null)return typeof e=="string"?e.slice(0,N):typeof URLSearchParams<"u"&&e instanceof URLSearchParams?e.toString().slice(0,N):"(binary)"}async function Te(e,t){let n=e.headers.get("content-type")||"";if(!/json|text|javascript|xml|html|csv/i.test(n)){t.responseBody={kind:"omitted"};return}try{let r=await e.clone().text();t.sizeBytes=r.length;let o=/json/i.test(n)?"json":"text";t.responseBody={kind:o,data:r.slice(0,N)}}catch{t.responseBody={kind:"omitted"}}}function xe(e){try{if(e.responseType===""||e.responseType==="text"){let t=e.responseText||"",n=e.getResponseHeader("content-type")||"";return{kind:/json/i.test(n)?"json":"text",data:t.slice(0,N)}}}catch{}return{kind:"omitted"}}var R=class{seq=0;byId=new Map;idOf=new WeakMap;idFor(t){let n=this.idOf.get(t);if(n)return this.byId.set(n,t),n;let r=`n${++this.seq}`;return this.idOf.set(t,r),this.byId.set(r,t),r}get(t){return this.byId.get(t)}clear(){this.byId.clear()}};function S(e){let t=e.getAttribute?.("data-id");if(t)return`[data-id=${t}]`;let n=e.getAttribute?.("role"),r=e.tagName.toLowerCase();return e.id?`${r}#${e.id}`:n?`${r}[role=${n}]`:r}var z="__ugly_inspect_overlay__";function q(e){if(typeof document>"u")return{setEnabled:()=>{},highlight:()=>{},destroy:()=>{}};let t=!1,n=null;function r(){if(n)return n;let a=document.createElement("div");return a.id=z,Object.assign(a.style,{position:"fixed",pointerEvents:"none",zIndex:"2147483647",background:"rgba(64,128,255,0.28)",border:"1px solid rgba(64,128,255,0.9)",boxSizing:"border-box",top:"0",left:"0",display:"none"}),document.documentElement.appendChild(a),n=a,a}function o(a){let d=r();if(!a){d.style.display="none";return}Object.assign(d.style,{display:"block",transform:`translate(${a.x}px, ${a.y}px)`,width:`${a.w}px`,height:`${a.h}px`})}let s=a=>{let d=c(a.clientX,a.clientY);d&&o(I(d))},i=a=>{let d=c(a.clientX,a.clientY);d&&(a.preventDefault(),a.stopPropagation(),e.setPickedNode(d),e.onPicked({nodeId:e.reg.idFor(d),selector:S(d),rect:I(d)}),l(!1))};function c(a,d){n&&(n.style.display="none");let g=document.elementFromPoint(a,d);return g&&g.id!==z?g:null}function l(a){a!==t&&(t=a,a?(window.addEventListener("pointermove",s,!0),window.addEventListener("pointerdown",i,!0)):(window.removeEventListener("pointermove",s,!0),window.removeEventListener("pointerdown",i,!0),o(null)))}function f(a){if(!a){o(null);return}let d=e.reg.get(a);d?.nodeType===1&&o(I(d))}return{setEnabled:l,highlight:f,destroy:()=>{l(!1),n?.remove(),n=null}}}function I(e){let t=e.getBoundingClientRect();return{x:t.x,y:t.y,w:t.width,h:t.height}}var G=4;async function Y(e,t){let n=t(),r=[];await new Promise(s=>{let i=()=>{r.push(Pe()),t()-n>=e?s():W(i)};W(i)});let o=t();return{startTime:n,endTime:o,durationMs:o-n,sampleCount:r.length,precise:!1,root:Le(r)}}function W(e){typeof setTimeout<"u"?setTimeout(e,G):e()}function Pe(){return y(new Error().stack,1).filter(t=>!/profile\.(js|ts)/.test(t.url)).map(t=>({url:t.url,line:t.line,col:t.col,functionName:t.functionName})).reverse()}function Le(e){let t=0,n=U(t++,"(root)");for(let r of e){let o=n;o.hitCount++;for(let s of r){let i=s,c=`${i.functionName??"(anonymous)"}@${i.url}:${i.line}`,l=o.childMap.get(c);l||(l=U(t++,i.functionName??"(anonymous)",{url:i.url,line:i.line,col:i.col}),o.childMap.set(c,l),o.children.push(l)),l.hitCount++,o=l}}return Q(n,e.length),J(n)}function U(e,t,n){return{id:e,functionName:t,source:n,selfTimeMs:0,totalTimeMs:0,hitCount:0,children:[],childMap:new Map}}function Q(e,t){let n=0;for(let r of e.children)n+=Q(r,t);return e.totalTimeMs=e.hitCount*G,e.selfTimeMs=Math.max(0,e.totalTimeMs-n),e.totalTimeMs}function J(e){return{id:e.id,functionName:e.functionName,source:e.source,selfTimeMs:e.selfTimeMs,totalTimeMs:e.totalTimeMs,hitCount:e.hitCount,children:e.children.map(t=>J(t))}}async function ee(){return{localStorage:K(Z(()=>localStorage)),sessionStorage:K(Z(()=>sessionStorage)),cookies:Ce(),indexedDB:await De()}}function Z(e){try{return e()}catch{return null}}function K(e){let t={};if(!e)return t;for(let n=0;n<e.length;n++){let r=e.key(n);r!=null&&(t[r]=e.getItem(r)??"")}return t}function Ce(){if(typeof document>"u"||!document.cookie)return[];let e=typeof location<"u"?location.hostname:"";return document.cookie.split("; ").filter(Boolean).map(t=>{let n=t.indexOf("="),r=n>=0?t.slice(0,n):t,o=n>=0?t.slice(n+1):"";return{name:r,value:o,domain:e,path:"/"}})}async function De(){if(typeof indexedDB>"u"||typeof indexedDB.databases!="function")return[];try{let e=await indexedDB.databases(),t=[];for(let n of e)n.name&&t.push({name:n.name,stores:await _e(n.name)});return t}catch{return[]}}function _e(e){return new Promise(t=>{try{let n=indexedDB.open(e);n.onsuccess=()=>{let r=n.result,o=Array.from(r.objectStoreNames);r.close(),t(o)},n.onerror=()=>t([])}catch{t([])}})}function te(e){let t={longTasks:[]},n=[];if(typeof PerformanceObserver>"u")return{read:()=>({...t,navigation:T()}),stop:()=>{}};r("largest-contentful-paint",o=>{let s=o[o.length-1];if(!s)return;let i=s.element;t.lcp={valueMs:s.startTime,element:i?{nodeId:e.nodeIdFor(i),selector:S(i),rect:je(i)}:void 0}}),r("paint",o=>{for(let s of o)s.name==="first-contentful-paint"&&(t.fcp=s.startTime)}),r("layout-shift",o=>{let s=t.cls??0;for(let i of o)i.hadRecentInput||(s+=i.value);t.cls=s}),r("event",o=>{let s=t.inp??0;for(let i of o){let c=i.duration;c>s&&(s=c)}t.inp=s},{durationThreshold:40}),r("longtask",o=>{for(let s of o)t.longTasks.push({ts:e.now(),durationMs:s.duration});t.longTasks.length>200&&t.longTasks.splice(0,t.longTasks.length-200)});function r(o,s,i){try{let c=new PerformanceObserver(l=>s(l.getEntries()));c.observe({type:o,buffered:!0,...i??{}}),n.push(c)}catch{}}return{read:()=>({...t,longTasks:t.longTasks.slice(),navigation:T(),ttfb:t.ttfb??T()?.ttfbMs}),stop:()=>n.forEach(o=>o.disconnect())}}function T(){if(typeof performance>"u"||!performance.getEntriesByType)return;let e=performance.getEntriesByType("navigation")[0];if(e)return{ttfbMs:e.responseStart,domContentLoadedMs:e.domContentLoadedEventEnd,loadEventMs:e.loadEventEnd,domInteractiveMs:e.domInteractive,transferSizeBytes:e.transferSize}}function je(e){let t=e.getBoundingClientRect();return{x:t.x,y:t.y,w:t.width,h:t.height}}var ne=1e3;function h(){return typeof performance<"u"&&performance.now?performance.timeOrigin+performance.now():Date.now()}function Ae(e={}){let t=new b,n=new R,r=u=>n.idFor(u),o=new w(ne),s=new w(ne),i=null,c,l=j({buffer:o,registry:t,nodeIdFor:r,onEntry:u=>e.onConsole?.(u),now:h}),f=H({buffer:s,onEntry:u=>e.onNetwork?.(u),now:h}),a=te({nodeIdFor:r,now:h}),d=q({reg:n,onPicked:u=>e.onPicked?.(u),setPickedNode:u=>i=u});return{meta(){return{url:typeof location<"u"?location.href:"",title:typeof document<"u"?document.title:"",isUglyApp:typeof window<"u"&&"__uglyInspect"in window,viewport:{w:typeof window<"u"?window.innerWidth:0,h:typeof window<"u"?window.innerHeight:0,dpr:typeof window<"u"&&window.devicePixelRatio||1}}},consoleBuffer:u=>u==null?o.all():o.all().filter(m=>m.seq>u),networkBuffer:u=>u==null?s.all():s.since(u,m=>m.ts),evaluate:(u,m)=>V(u,{registry:t,nodeIdFor:r,now:h,getPicked:()=>i,getLast:()=>c,setLast:re=>c=re},m),expand:u=>({entries:P(t.get(u),{registry:t,nodeIdFor:r})}),domCapture:u=>$(n,u,h),element:u=>B(n,u),highlight:u=>d.highlight(u),setPicker:u=>d.setEnabled(u),vitals:()=>a.read(),profile:u=>Y(u,h),storage:()=>ee(),reset:()=>{t.clear(),n.clear(),o.clear(),s.clear(),i=null,c=void 0},stop:()=>{l(),f(),a.stop(),d.destroy()}}}function oe(e){if(typeof window<"u"&&window.__uglyInspectAgent)return window.__uglyInspectAgent;let t=Ae(e);return typeof window<"u"&&(window.__uglyInspectAgent=t),t}oe();})();
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { InspectClient } from '../client.js';
|
|
2
|
+
export interface InspectPanelProps {
|
|
3
|
+
client: InspectClient;
|
|
4
|
+
/** Poll interval for the target list (ms). 0 disables polling. */
|
|
5
|
+
targetPollMs?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function InspectPanel({ client, targetPollMs }: InspectPanelProps): import("react").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=InspectPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InspectPanel.d.ts","sourceRoot":"","sources":["../../../src/inspect/ui/InspectPanel.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAmBlD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,aAAa,CAAC;IACtB,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,YAAmB,EAAE,EAAE,iBAAiB,+BAiE9E"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// The desktop inspect UI shell: device/target picker, tab rail, and the active
|
|
3
|
+
// panel. Driven entirely by an InspectClient, so the SAME component embeds in
|
|
4
|
+
// Ugly Studio (privileged surface) and in ugly-code. Self-contained styling.
|
|
5
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
6
|
+
import { ConsolePanel } from './panels/ConsolePanel.js';
|
|
7
|
+
import { ElementsPanel } from './panels/ElementsPanel.js';
|
|
8
|
+
import { NetworkPanel } from './panels/NetworkPanel.js';
|
|
9
|
+
import { PerformancePanel } from './panels/PerformancePanel.js';
|
|
10
|
+
import { StoragePanel } from './panels/StoragePanel.js';
|
|
11
|
+
import { ensureInspectStyles, INSPECT_ROOT } from './styles.js';
|
|
12
|
+
const TABS = [
|
|
13
|
+
{ key: 'elements', label: 'Elements' },
|
|
14
|
+
{ key: 'console', label: 'Console' },
|
|
15
|
+
{ key: 'network', label: 'Network' },
|
|
16
|
+
{ key: 'performance', label: 'Performance' },
|
|
17
|
+
{ key: 'application', label: 'Application' },
|
|
18
|
+
{ key: 'screenshot', label: 'Capture' },
|
|
19
|
+
];
|
|
20
|
+
export function InspectPanel({ client, targetPollMs = 4000 }) {
|
|
21
|
+
ensureInspectStyles();
|
|
22
|
+
const [targets, setTargets] = useState([]);
|
|
23
|
+
const [targetId, setTargetId] = useState(null);
|
|
24
|
+
const [tab, setTab] = useState('elements');
|
|
25
|
+
const loadTargets = useCallback(() => {
|
|
26
|
+
void client.listTargets().then((ts) => {
|
|
27
|
+
setTargets(ts);
|
|
28
|
+
setTargetId((cur) => (cur && ts.some((t) => t.id === cur) ? cur : ts[0]?.id ?? null));
|
|
29
|
+
});
|
|
30
|
+
}, [client]);
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
loadTargets();
|
|
33
|
+
if (!targetPollMs)
|
|
34
|
+
return;
|
|
35
|
+
const h = setInterval(loadTargets, targetPollMs);
|
|
36
|
+
return () => clearInterval(h);
|
|
37
|
+
}, [loadTargets, targetPollMs]);
|
|
38
|
+
const current = targets.find((t) => t.id === targetId) ?? null;
|
|
39
|
+
return (_jsxs("div", { className: INSPECT_ROOT, children: [_jsxs("div", { className: "ins-topbar", children: [_jsx("span", { className: "ins-brand", children: "Inspect" }), _jsxs("select", { className: "ins-select", value: targetId ?? '', onChange: (e) => setTargetId(e.target.value), title: current?.url, children: [targets.length === 0 && _jsx("option", { value: "", children: "no targets" }), targets.map((t) => (_jsxs("option", { value: t.id, children: [t.platform === 'desktop' ? '🖥' : t.platform === 'ios' ? '' : '', " ", t.title || hostOf(t.url), " \u2014 ", hostOf(t.url)] }, t.id)))] }), _jsx("span", { className: "ins-spacer" }), _jsx("button", { className: "ins-btn", onClick: loadTargets, title: "refresh targets", children: "\u21BB" })] }), _jsx("div", { className: "ins-tabs", children: TABS.map((t) => (_jsx("span", { className: "ins-tab", "data-active": tab === t.key, onClick: () => setTab(t.key), children: t.label }, t.key))) }), _jsx("div", { className: "ins-body", children: !targetId || !current ? (_jsxs("div", { className: "ins-empty", children: [_jsx("b", { children: "No target" }), "open a tab to inspect, then refresh"] })) : (_jsx(ActivePanel, { tab: tab, client: client, targetId: targetId }, `${targetId}:${tab}`)) })] }));
|
|
40
|
+
}
|
|
41
|
+
function ActivePanel({ tab, client, targetId }) {
|
|
42
|
+
switch (tab) {
|
|
43
|
+
case 'console':
|
|
44
|
+
return _jsx(ConsolePanel, { client: client, targetId: targetId });
|
|
45
|
+
case 'elements':
|
|
46
|
+
return _jsx(ElementsPanel, { client: client, targetId: targetId });
|
|
47
|
+
case 'network':
|
|
48
|
+
return _jsx(NetworkPanel, { client: client, targetId: targetId });
|
|
49
|
+
case 'performance':
|
|
50
|
+
return _jsx(PerformancePanel, { client: client, targetId: targetId });
|
|
51
|
+
case 'application':
|
|
52
|
+
return _jsx(StoragePanel, { client: client, targetId: targetId });
|
|
53
|
+
case 'screenshot':
|
|
54
|
+
return _jsx(ScreenshotPanel, { client: client, targetId: targetId });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function ScreenshotPanel({ client, targetId }) {
|
|
58
|
+
const [shot, setShot] = useState(null);
|
|
59
|
+
const [busy, setBusy] = useState(false);
|
|
60
|
+
const capture = async (fullPage) => {
|
|
61
|
+
setBusy(true);
|
|
62
|
+
try {
|
|
63
|
+
setShot(await client.screenshot({ targetId, fullPage }));
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
setBusy(false);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
return (_jsxs("div", { className: "ins-panel", children: [_jsxs("div", { className: "ins-status-line", children: [_jsx("button", { className: "ins-btn", disabled: busy, onClick: () => void capture(false), children: "\u25A2 viewport" }), _jsx("button", { className: "ins-btn", disabled: busy, onClick: () => void capture(true), children: "\u25A4 full page" }), shot && (_jsxs("span", { children: [shot.width, "\u00D7", shot.height, " @", shot.dpr, "x"] }))] }), _jsx("div", { className: "ins-scroll", children: shot ? (_jsx("img", { className: "ins-shot", src: `data:image/${shot.format};base64,${shot.base64}`, alt: "screenshot" })) : (_jsxs("div", { className: "ins-empty", children: [_jsx("b", { children: "Capture" }), busy ? 'capturing…' : 'screenshot the current target'] })) })] }));
|
|
70
|
+
}
|
|
71
|
+
function hostOf(url) {
|
|
72
|
+
try {
|
|
73
|
+
return new URL(url).host;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return url;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=InspectPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InspectPanel.js","sourceRoot":"","sources":["../../../src/inspect/ui/InspectPanel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InspectPanel.test.d.ts","sourceRoot":"","sources":["../../../src/inspect/ui/InspectPanel.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// @vitest-environment jsdom
|
|
3
|
+
import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react';
|
|
4
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
5
|
+
import { InspectPanel } from './InspectPanel.js';
|
|
6
|
+
afterEach(cleanup);
|
|
7
|
+
const TARGET = {
|
|
8
|
+
id: 'tab-1',
|
|
9
|
+
url: 'https://example.test/app',
|
|
10
|
+
title: 'Example',
|
|
11
|
+
viewport: { w: 800, h: 600, dpr: 2 },
|
|
12
|
+
platform: 'desktop',
|
|
13
|
+
isUglyApp: true,
|
|
14
|
+
};
|
|
15
|
+
function fakeClient(over = {}) {
|
|
16
|
+
const noop = () => () => { };
|
|
17
|
+
return {
|
|
18
|
+
listTargets: vi.fn(async () => [TARGET]),
|
|
19
|
+
captureDom: vi.fn(async () => ({
|
|
20
|
+
documentUrl: TARGET.url,
|
|
21
|
+
capturedAt: 0,
|
|
22
|
+
root: { nodeId: 'n1', nodeType: 1, nodeName: 'HTML', children: [] },
|
|
23
|
+
})),
|
|
24
|
+
element: vi.fn(),
|
|
25
|
+
highlight: vi.fn(async () => { }),
|
|
26
|
+
setPicker: vi.fn(async () => { }),
|
|
27
|
+
onPicked: vi.fn(noop),
|
|
28
|
+
onConsole: vi.fn(noop),
|
|
29
|
+
onNetwork: vi.fn(noop),
|
|
30
|
+
consoleBuffer: vi.fn(async () => []),
|
|
31
|
+
networkBuffer: vi.fn(async () => []),
|
|
32
|
+
eval: vi.fn(async () => ({ ok: true, tookMs: 1 })),
|
|
33
|
+
expand: vi.fn(async () => []),
|
|
34
|
+
vitals: vi.fn(async () => ({ longTasks: [] })),
|
|
35
|
+
profile: vi.fn(),
|
|
36
|
+
storage: vi.fn(),
|
|
37
|
+
screenshot: vi.fn(),
|
|
38
|
+
...over,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
describe('InspectPanel', () => {
|
|
42
|
+
it('lists targets and shows the picker', async () => {
|
|
43
|
+
const client = fakeClient();
|
|
44
|
+
render(_jsx(InspectPanel, { client: client, targetPollMs: 0 }));
|
|
45
|
+
await waitFor(() => expect(client.listTargets).toHaveBeenCalled());
|
|
46
|
+
expect(await screen.findByText(/Example/)).toBeTruthy();
|
|
47
|
+
expect(screen.getByText('Inspect')).toBeTruthy();
|
|
48
|
+
});
|
|
49
|
+
it('captures the DOM for the default (Elements) tab', async () => {
|
|
50
|
+
const client = fakeClient();
|
|
51
|
+
render(_jsx(InspectPanel, { client: client, targetPollMs: 0 }));
|
|
52
|
+
await waitFor(() => expect(client.captureDom).toHaveBeenCalledWith('tab-1'));
|
|
53
|
+
expect(await screen.findByText(/html/)).toBeTruthy();
|
|
54
|
+
});
|
|
55
|
+
it('switches to Console and runs a REPL eval', async () => {
|
|
56
|
+
const evalFn = vi.fn(async () => ({ ok: true, value: { type: 'number', value: 42 }, tookMs: 1 }));
|
|
57
|
+
const client = fakeClient({ eval: evalFn });
|
|
58
|
+
render(_jsx(InspectPanel, { client: client, targetPollMs: 0 }));
|
|
59
|
+
await waitFor(() => expect(client.listTargets).toHaveBeenCalled());
|
|
60
|
+
fireEvent.click(screen.getByText('Console'));
|
|
61
|
+
const input = await screen.findByPlaceholderText(/evaluate/);
|
|
62
|
+
fireEvent.change(input, { target: { value: '40 + 2' } });
|
|
63
|
+
fireEvent.submit(input);
|
|
64
|
+
await waitFor(() => expect(evalFn).toHaveBeenCalledWith(expect.objectContaining({ targetId: 'tab-1', expression: '40 + 2' })));
|
|
65
|
+
expect(await screen.findByText('42')).toBeTruthy();
|
|
66
|
+
});
|
|
67
|
+
it('shows web vitals on the Performance tab', async () => {
|
|
68
|
+
const client = fakeClient({ vitals: vi.fn(async () => ({ lcp: { valueMs: 1200 }, cls: 0.02, longTasks: [] })) });
|
|
69
|
+
render(_jsx(InspectPanel, { client: client, targetPollMs: 0 }));
|
|
70
|
+
await waitFor(() => expect(client.listTargets).toHaveBeenCalled());
|
|
71
|
+
fireEvent.click(screen.getByText('Performance'));
|
|
72
|
+
await waitFor(() => expect(client.vitals).toHaveBeenCalledWith('tab-1'));
|
|
73
|
+
expect(await screen.findByText('lcp')).toBeTruthy();
|
|
74
|
+
expect(await screen.findByText('1200')).toBeTruthy();
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
//# sourceMappingURL=InspectPanel.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InspectPanel.test.js","sourceRoot":"","sources":["../../../src/inspect/ui/InspectPanel.test.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RemoteValue } from '../protocol.js';
|
|
2
|
+
export interface RemoteValueViewProps {
|
|
3
|
+
value: RemoteValue;
|
|
4
|
+
/** Lazy-expand a composite by objectId → its full child entries. */
|
|
5
|
+
expand?: (objectId: string) => Promise<RemoteValue[]>;
|
|
6
|
+
/** Render the top node already expanded (used for the REPL result line). */
|
|
7
|
+
defaultOpen?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function RemoteValueView({ value, expand, defaultOpen }: RemoteValueViewProps): import("react").JSX.Element;
|
|
10
|
+
//# sourceMappingURL=RemoteValueView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RemoteValueView.d.ts","sourceRoot":"","sources":["../../../src/inspect/ui/RemoteValueView.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,WAAW,CAAC;IACnB,oEAAoE;IACpE,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACtD,4EAA4E;IAC5E,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,oBAAoB,+BAMnF"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// Renders a structured RemoteValue: primitives inline, composites collapsible
|
|
3
|
+
// with lazy expansion (inspect.expand by objectId). Used by the Console + REPL.
|
|
4
|
+
import { useState } from 'react';
|
|
5
|
+
export function RemoteValueView({ value, expand, defaultOpen }) {
|
|
6
|
+
return (_jsx("span", { className: "ins-rv", children: _jsx(Node, { value: value, expand: expand, open: defaultOpen }) }));
|
|
7
|
+
}
|
|
8
|
+
function Node({ value, expand, open }) {
|
|
9
|
+
const composite = isComposite(value);
|
|
10
|
+
const [isOpen, setOpen] = useState(!!open);
|
|
11
|
+
const [children, setChildren] = useState(null);
|
|
12
|
+
const [loading, setLoading] = useState(false);
|
|
13
|
+
if (!composite)
|
|
14
|
+
return _jsx(Primitive, { value: value });
|
|
15
|
+
const toggle = async () => {
|
|
16
|
+
const next = !isOpen;
|
|
17
|
+
setOpen(next);
|
|
18
|
+
if (next && children === null && value.objectId && expand) {
|
|
19
|
+
setLoading(true);
|
|
20
|
+
try {
|
|
21
|
+
setChildren(await expand(value.objectId));
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
setChildren([]);
|
|
25
|
+
}
|
|
26
|
+
finally {
|
|
27
|
+
setLoading(false);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const preview = value.preview ?? value.className ?? value.type;
|
|
32
|
+
// Synchronous preview entries (from the initial serialize) are shown before a
|
|
33
|
+
// full expand is fetched.
|
|
34
|
+
const shown = children ?? value.entries?.map((e) => e.value) ?? null;
|
|
35
|
+
const keys = value.entries?.map((e) => keyLabel(e.key)) ?? [];
|
|
36
|
+
return (_jsxs("span", { children: [_jsxs("span", { className: "ins-rv-toggle", onClick: () => void toggle(), children: [isOpen ? '▾ ' : '▸ ', _jsx("span", { className: classFor(value), children: preview })] }), isOpen && (_jsxs("span", { className: "ins-rv-children", style: { display: 'block' }, children: [loading && _jsx("span", { className: "ins-rv-null", children: "\u2026" }), shown?.map((child, i) => (_jsxs("span", { style: { display: 'block' }, children: [keys[i] != null && _jsxs("span", { className: "ins-rv-key", children: [keys[i], ": "] }), _jsx(Node, { value: child, expand: expand })] }, i)))] }))] }));
|
|
37
|
+
}
|
|
38
|
+
function Primitive({ value }) {
|
|
39
|
+
switch (value.type) {
|
|
40
|
+
case 'string':
|
|
41
|
+
return _jsxs("span", { className: "ins-rv-str", children: ["\"", String(value.value), "\""] });
|
|
42
|
+
case 'number':
|
|
43
|
+
case 'bigint':
|
|
44
|
+
return _jsx("span", { className: "ins-rv-num", children: String(value.value ?? value.preview) });
|
|
45
|
+
case 'boolean':
|
|
46
|
+
return _jsx("span", { className: "ins-rv-bool", children: String(value.value) });
|
|
47
|
+
case 'undefined':
|
|
48
|
+
return _jsx("span", { className: "ins-rv-null", children: "undefined" });
|
|
49
|
+
case 'null':
|
|
50
|
+
return _jsx("span", { className: "ins-rv-null", children: "null" });
|
|
51
|
+
case 'node':
|
|
52
|
+
return _jsx("span", { className: "ins-rv-node", children: value.preview ?? '<node>' });
|
|
53
|
+
case 'function':
|
|
54
|
+
return _jsx("span", { className: "ins-rv-fn", children: value.preview ?? 'ƒ' });
|
|
55
|
+
default:
|
|
56
|
+
return _jsx("span", { className: "ins-rv-null", children: value.preview ?? String(value.value ?? value.type) });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function isComposite(v) {
|
|
60
|
+
return v.type === 'object' || v.type === 'array' || v.type === 'map' || v.type === 'set' || v.type === 'error';
|
|
61
|
+
}
|
|
62
|
+
function classFor(v) {
|
|
63
|
+
if (v.type === 'node')
|
|
64
|
+
return 'ins-rv-node';
|
|
65
|
+
return 'ins-rv-null';
|
|
66
|
+
}
|
|
67
|
+
function keyLabel(key) {
|
|
68
|
+
if (key == null)
|
|
69
|
+
return null;
|
|
70
|
+
if (typeof key === 'string')
|
|
71
|
+
return key;
|
|
72
|
+
return key.preview ?? String(key.value ?? key.type);
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=RemoteValueView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RemoteValueView.js","sourceRoot":"","sources":["../../../src/inspect/ui/RemoteValueView.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/inspect/ui/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAClF,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Reusable desktop inspect UI — a self-contained React surface driven by an
|
|
2
|
+
// InspectClient. Embedded by Ugly Studio (privileged shell view) and ugly-code.
|
|
3
|
+
export { InspectPanel } from './InspectPanel.js';
|
|
4
|
+
export { RemoteValueView } from './RemoteValueView.js';
|
|
5
|
+
export { ensureInspectStyles, INSPECT_ROOT } from './styles.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/inspect/ui/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,gFAAgF;AAEhF,OAAO,EAAE,YAAY,EAA0B,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,eAAe,EAA6B,MAAM,sBAAsB,CAAC;AAClF,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConsolePanel.d.ts","sourceRoot":"","sources":["../../../../src/inspect/ui/panels/ConsolePanel.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAYrD,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,+BAoF7F"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// Console panel: live log stream + REPL eval. Logs render structured (level
|
|
3
|
+
// gutter, source loc); the REPL shows each result as an expandable RemoteValue.
|
|
4
|
+
import { useEffect, useRef, useState } from 'react';
|
|
5
|
+
import { RemoteValueView } from '../RemoteValueView.js';
|
|
6
|
+
const GUTTER = { log: '·', info: 'i', warn: '!', error: '✕', debug: '⋯' };
|
|
7
|
+
export function ConsolePanel({ client, targetId }) {
|
|
8
|
+
const [entries, setEntries] = useState([]);
|
|
9
|
+
const [repl, setRepl] = useState([]);
|
|
10
|
+
const [input, setInput] = useState('');
|
|
11
|
+
const scrollRef = useRef(null);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
let live = true;
|
|
14
|
+
setEntries([]);
|
|
15
|
+
setRepl([]);
|
|
16
|
+
void client.consoleBuffer(targetId).then((b) => live && setEntries(b));
|
|
17
|
+
const off = client.onConsole(targetId, (e) => setEntries((cur) => [...cur, e].slice(-2000)));
|
|
18
|
+
return () => {
|
|
19
|
+
live = false;
|
|
20
|
+
off();
|
|
21
|
+
};
|
|
22
|
+
}, [client, targetId]);
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const el = scrollRef.current;
|
|
25
|
+
if (el)
|
|
26
|
+
el.scrollTop = el.scrollHeight;
|
|
27
|
+
}, [entries, repl]);
|
|
28
|
+
const run = async () => {
|
|
29
|
+
const expr = input.trim();
|
|
30
|
+
if (!expr)
|
|
31
|
+
return;
|
|
32
|
+
setInput('');
|
|
33
|
+
setRepl((cur) => [...cur, { kind: 'input', text: expr }]);
|
|
34
|
+
const res = await client.eval({ targetId, expression: expr, awaitPromise: true, replMode: true });
|
|
35
|
+
setRepl((cur) => res.ok
|
|
36
|
+
? [...cur, { kind: 'result', value: res.value }]
|
|
37
|
+
: [...cur, { kind: 'error', text: res.exception?.text ?? 'error' }]);
|
|
38
|
+
};
|
|
39
|
+
const expand = (objectId) => client.expand(targetId, objectId);
|
|
40
|
+
return (_jsxs("div", { className: "ins-panel", children: [_jsxs("div", { className: "ins-scroll", ref: scrollRef, children: [entries.length === 0 && repl.length === 0 && (_jsxs("div", { className: "ins-empty", children: [_jsx("b", { children: "Console" }), "console output streams here \u00B7 type below to evaluate"] })), entries.map((e) => (_jsxs("div", { className: "ins-log-row", "data-level": e.level, children: [_jsx("span", { className: "ins-log-gutter", children: GUTTER[e.level] ?? '·' }), _jsx("span", { className: "ins-log-body", children: e.text }), e.source?.url && (_jsxs("span", { className: "ins-log-src", children: [shortUrl(e.source.url), ":", e.source.line] }))] }, `c${e.seq}`))), repl.map((line, i) => (_jsxs("div", { className: "ins-log-row", "data-level": line.kind === 'error' ? 'error' : 'log', children: [_jsx("span", { className: "ins-log-gutter", children: line.kind === 'input' ? '›' : line.kind === 'error' ? '✕' : '‹' }), _jsx("span", { className: "ins-log-body", children: line.value ? _jsx(RemoteValueView, { value: line.value, expand: expand, defaultOpen: true }) : line.text })] }, `r${i}`)))] }), _jsx("form", { className: "ins-repl", onSubmit: (e) => {
|
|
41
|
+
e.preventDefault();
|
|
42
|
+
void run();
|
|
43
|
+
}, children: _jsx("input", { value: input, onChange: (e) => setInput(e.target.value), placeholder: "evaluate expression\u2026", spellCheck: false, autoComplete: "off" }) })] }));
|
|
44
|
+
}
|
|
45
|
+
function shortUrl(url) {
|
|
46
|
+
try {
|
|
47
|
+
const u = new URL(url);
|
|
48
|
+
const parts = u.pathname.split('/');
|
|
49
|
+
return parts[parts.length - 1] || u.hostname;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return url.slice(-24);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=ConsolePanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConsolePanel.js","sourceRoot":"","sources":["../../../../src/inspect/ui/panels/ConsolePanel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ElementsPanel.d.ts","sourceRoot":"","sources":["../../../../src/inspect/ui/panels/ElementsPanel.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGrD,wBAAgB,aAAa,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,+BAyE9F"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
// Elements panel: DOM tree on the left, selected-element detail on the right
|
|
3
|
+
// (computed styles, box model, attributes, a11y). Picker toggle drives the
|
|
4
|
+
// in-page overlay; a pick selects the node here.
|
|
5
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
6
|
+
export function ElementsPanel({ client, targetId }) {
|
|
7
|
+
const [snap, setSnap] = useState(null);
|
|
8
|
+
const [selected, setSelected] = useState(null);
|
|
9
|
+
const [detail, setDetail] = useState(null);
|
|
10
|
+
const [picking, setPicking] = useState(false);
|
|
11
|
+
const refresh = useCallback(() => {
|
|
12
|
+
void client.captureDom(targetId).then(setSnap);
|
|
13
|
+
}, [client, targetId]);
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
setSnap(null);
|
|
16
|
+
setSelected(null);
|
|
17
|
+
setDetail(null);
|
|
18
|
+
refresh();
|
|
19
|
+
}, [refresh]);
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
const off = client.onPicked(targetId, (p) => {
|
|
22
|
+
setPicking(false);
|
|
23
|
+
void select(p.nodeId);
|
|
24
|
+
});
|
|
25
|
+
return off;
|
|
26
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
27
|
+
}, [client, targetId]);
|
|
28
|
+
const select = async (nodeId) => {
|
|
29
|
+
setSelected(nodeId);
|
|
30
|
+
void client.highlight(targetId, nodeId);
|
|
31
|
+
try {
|
|
32
|
+
setDetail(await client.element(targetId, { nodeId }));
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
setDetail(null);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const togglePick = () => {
|
|
39
|
+
const next = !picking;
|
|
40
|
+
setPicking(next);
|
|
41
|
+
void client.setPicker(targetId, next);
|
|
42
|
+
};
|
|
43
|
+
return (_jsxs("div", { className: "ins-panel", children: [_jsxs("div", { className: "ins-status-line", children: [_jsx("button", { className: "ins-btn", "data-on": picking, onClick: togglePick, children: "\u2316 pick" }), _jsx("button", { className: "ins-btn", onClick: refresh, children: "\u21BB recapture" }), _jsx("span", { style: { flex: 1 } }), _jsx("span", { children: snap ? `${countNodes(snap.root)} nodes` : 'capturing…' })] }), _jsxs("div", { className: "ins-split", children: [_jsx("div", { className: "ins-scroll", children: snap ? (_jsx("div", { className: "ins-tree", children: _jsx(TreeNode, { node: snap.root, depth: 0, selected: selected, onSelect: (id) => void select(id) }) })) : (_jsxs("div", { className: "ins-empty", children: [_jsx("b", { children: "DOM" }), "capturing tree\u2026"] })) }), _jsx("div", { className: "ins-detail", children: detail ? _jsx(ElementDetailView, { detail: detail }) : _jsxs("div", { className: "ins-empty", children: [_jsx("b", { children: "element" }), "select a node"] }) })] })] }));
|
|
44
|
+
}
|
|
45
|
+
function TreeNode({ node, depth, selected, onSelect, }) {
|
|
46
|
+
const kids = [...(node.shadowRoots ?? []), ...(node.children ?? [])];
|
|
47
|
+
const [open, setOpen] = useState(depth < 2);
|
|
48
|
+
const hasKids = kids.length > 0;
|
|
49
|
+
if (node.nodeType === 3) {
|
|
50
|
+
return (_jsxs("div", { className: "ins-node-row", style: { paddingLeft: 10 + depth * 13 }, children: [_jsx("span", { className: "ins-twirl" }), _jsxs("span", { className: "ins-text-node", children: ["\"", node.textContent, "\""] })] }));
|
|
51
|
+
}
|
|
52
|
+
if (node.nodeType !== 1 && node.nodeType !== 9)
|
|
53
|
+
return null;
|
|
54
|
+
return (_jsxs("div", { children: [_jsxs("div", { className: "ins-node-row", "data-sel": selected === node.nodeId, style: { paddingLeft: 10 + depth * 13 }, onClick: () => onSelect(node.nodeId), children: [_jsx("span", { className: "ins-twirl", onClick: (e) => {
|
|
55
|
+
e.stopPropagation();
|
|
56
|
+
setOpen((o) => !o);
|
|
57
|
+
}, children: hasKids ? (open ? '▾' : '▸') : '' }), _jsxs("span", { children: [_jsxs("span", { className: "ins-tag", children: ["<", node.nodeName.toLowerCase()] }), _jsx(Attrs, { node: node }), _jsx("span", { className: "ins-tag", children: ">" })] })] }), open &&
|
|
58
|
+
kids.map((k, i) => (_jsx(TreeNode, { node: k, depth: depth + 1, selected: selected, onSelect: onSelect }, k.nodeId || i)))] }));
|
|
59
|
+
}
|
|
60
|
+
function Attrs({ node }) {
|
|
61
|
+
const attrs = Object.entries(node.attributes ?? {}).slice(0, 6);
|
|
62
|
+
return (_jsx(_Fragment, { children: attrs.map(([k, v]) => (_jsxs("span", { children: [' ', _jsx("span", { className: "ins-attr-name", children: k }), v !== '' && (_jsxs(_Fragment, { children: ["=", _jsxs("span", { className: "ins-attr-val", children: ["\"", truncate(v, 40), "\""] })] }))] }, k))) }));
|
|
63
|
+
}
|
|
64
|
+
function ElementDetailView({ detail }) {
|
|
65
|
+
const bm = detail.boxModel;
|
|
66
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "ins-detail-sec", children: [_jsx("h4", { children: detail.tag }), _jsx("div", { className: "ins-box", children: _jsxs("div", { className: "ins-box-layer", children: [_jsxs("span", { className: "ins-box-label", children: ["margin ", fmtQuad(bm.margin)] }), _jsxs("div", { className: "ins-box-layer", children: [_jsxs("span", { className: "ins-box-label", children: ["border ", fmtQuad(bm.border)] }), _jsxs("div", { className: "ins-box-layer", children: [_jsxs("span", { className: "ins-box-label", children: ["padding ", fmtQuad(bm.padding)] }), _jsxs("div", { className: "ins-box-content", children: [Math.round(bm.content.w), " \u00D7 ", Math.round(bm.content.h)] })] })] })] }) })] }), Object.keys(detail.attributes).length > 0 && (_jsxs("div", { className: "ins-detail-sec", children: [_jsx("h4", { children: "attributes" }), _jsx("dl", { className: "ins-kv", children: Object.entries(detail.attributes).map(([k, v]) => (_jsxs("div", { style: { display: 'contents' }, children: [_jsx("dt", { children: k }), _jsx("dd", { children: v })] }, k))) })] })), detail.accessibility && (detail.accessibility.role || detail.accessibility.name) && (_jsxs("div", { className: "ins-detail-sec", children: [_jsx("h4", { children: "accessibility" }), _jsxs("dl", { className: "ins-kv", children: [detail.accessibility.role && (_jsxs("div", { style: { display: 'contents' }, children: [_jsx("dt", { children: "role" }), _jsx("dd", { children: detail.accessibility.role })] })), detail.accessibility.name && (_jsxs("div", { style: { display: 'contents' }, children: [_jsx("dt", { children: "name" }), _jsx("dd", { children: detail.accessibility.name })] }))] })] })), _jsxs("div", { className: "ins-detail-sec", children: [_jsx("h4", { children: "computed" }), _jsx("dl", { className: "ins-kv", children: Object.entries(detail.computedStyles)
|
|
67
|
+
.filter(([, v]) => v && v !== 'none' && v !== 'normal' && v !== 'auto')
|
|
68
|
+
.slice(0, 120)
|
|
69
|
+
.map(([k, v]) => (_jsxs("div", { style: { display: 'contents' }, children: [_jsx("dt", { children: k }), _jsx("dd", { children: v })] }, k))) })] })] }));
|
|
70
|
+
}
|
|
71
|
+
function fmtQuad(q) {
|
|
72
|
+
const r = (n) => Math.round(n);
|
|
73
|
+
return `${r(q.top)} ${r(q.right)} ${r(q.bottom)} ${r(q.left)}`;
|
|
74
|
+
}
|
|
75
|
+
function truncate(s, n) {
|
|
76
|
+
return s.length > n ? `${s.slice(0, n)}…` : s;
|
|
77
|
+
}
|
|
78
|
+
function countNodes(node) {
|
|
79
|
+
let n = 1;
|
|
80
|
+
for (const k of [...(node.children ?? []), ...(node.shadowRoots ?? [])])
|
|
81
|
+
n += countNodes(k);
|
|
82
|
+
return n;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=ElementsPanel.js.map
|