UNPKG

@react-native/debugger-frontend

Version:
2 lines (1 loc) • 17.3 kB
import*as e from"./extras/extras.js";export{e as Extras};import*as t from"./handlers/handlers.js";export{t as Handlers};import*as r from"./helpers/helpers.js";export{r as Helpers};import*as n from"./insights/insights.js";export{n as Insights};import*as s from"./lantern/lantern.js";export{s as Lantern};import*as a from"../../core/platform/platform.js";import*as i from"./types/types.js";export{i as Types};import*as o from"../../core/sdk/sdk.js";function c(e,t,r){const n=e.PageLoadMetrics.metricScoresByFrameId.get(t);if(!n)throw new s.Core.LanternError("missing metric scores for frame");const a=n.get(r);if(!a)throw new s.Core.LanternError("missing metric scores for specified navigation");return{timestamps:{firstContentfulPaint:(e=>{const t=a.get(e);if(!t?.event)throw new s.Core.LanternError(`missing metric: ${e}`);return t.event.ts})("FCP"),largestContentfulPaint:(e=>{const t=a.get(e);if(t?.event)return t.event.ts})("LCP")}}}function l(e){return"string"==typeof e&&(e=new URL(e)),{scheme:e.protocol.split(":")[0],host:e.hostname,securityOrigin:e.origin}}function d(e,t,r){if(void 0===r.args.data.connectionId||void 0===r.args.data.connectionReused)throw new s.Core.LanternError("Trace is too old");let n;try{n=new URL(r.args.data.url)}catch{return}const a=r.args.data.timing?{workerFetchStart:-1,workerRespondWithSettled:-1,...r.args.data.timing}:void 0,i=a?1e3*a.requestTime:r.args.data.syntheticData.downloadStart/1e3;let o=!1;const c=t.get(r.pid);c?.includes(r.tid)&&(o=!0),e.Workers.workerIdByThread.has(r.tid)&&(o=!0);const d=r.args.data.initiator??{type:"other"};if(r.args.data.stackTrace){const e=r.args.data.stackTrace.map((e=>({scriptId:String(e.scriptId),url:e.url,lineNumber:e.lineNumber-1,columnNumber:e.columnNumber-1,functionName:e.functionName})));d.stack={callFrames:e}}let g=r.args.data.resourceType;"xmlhttprequest"===r.args.data.initiator?.fetchType?g="XHR":"fetch"===r.args.data.initiator?.fetchType&&(g="Fetch");let h=r.args.data.decodedBodyLength??0;if("data:"===n.protocol&&0===h){const e=n.pathname.indexOf(",");h=n.pathname.substring(0,e).includes(";base64")?atob(n.pathname.substring(e+1)).length:n.pathname.length-e-1}return{rawRequest:r,requestId:r.args.data.requestId,connectionId:r.args.data.connectionId,connectionReused:r.args.data.connectionReused,url:r.args.data.url,protocol:r.args.data.protocol,parsedURL:l(n),documentURL:r.args.data.requestingFrameUrl,rendererStartTime:r.ts/1e3,networkRequestTime:i,responseHeadersEndTime:r.args.data.syntheticData.downloadStart/1e3,networkEndTime:r.args.data.syntheticData.finishTime/1e3,transferSize:r.args.data.encodedDataLength,resourceSize:h,fromDiskCache:r.args.data.syntheticData.isDiskCached,fromMemoryCache:r.args.data.syntheticData.isMemoryCached,isLinkPreload:r.args.data.isLinkPreload,finished:r.args.data.finished,failed:r.args.data.failed,statusCode:r.args.data.statusCode,initiator:d,timing:a,resourceType:g,mimeType:r.args.data.mimeType,priority:r.args.data.priority,frameId:r.args.data.frame,fromWorker:o,redirects:void 0,redirectSource:void 0,redirectDestination:void 0,initiatorRequest:void 0}}function g(e,t){if(e.redirectSource)return e.redirectSource;const r=s.Graph.PageDependencyGraph.getNetworkInitiators(e)[0];let n=t.get(r)||[];if(n=n.filter((t=>t.responseHeadersEndTime<=e.rendererStartTime&&t.finished&&!t.failed)),n.length>1){const e=n.filter((e=>e.resourceType!==s.Types.NetworkRequestTypes.Other));e.length&&(n=e)}if(n.length>1){const t=n.filter((t=>t.frameId===e.frameId));t.length&&(n=t)}if(n.length>1&&"parser"===e.initiator.type){const e=n.filter((e=>e.resourceType===s.Types.NetworkRequestTypes.Document));e.length&&(n=e)}if(n.length>1){const e=n.filter((e=>e.isLinkPreload));if(e.length){const t=n.filter((e=>!e.isLinkPreload)),r=t.every((e=>e.fromDiskCache||e.fromMemoryCache));t.length&&r&&(n=e)}}return 1===n.length?n[0]:null}function h(e,t,r=0,n=Number.POSITIVE_INFINITY){const s=function(e){const t=new Map,r=["ServiceWorker thread","DedicatedWorker thread"];for(const n of e.traceEvents){if("thread_name"!==n.name||!n.args.name)continue;if(!r.includes(n.args.name))continue;const e=t.get(n.pid);e?e.push(n.tid):t.set(n.pid,[n.tid])}return t}(e),a=[];for(const e of t.NetworkRequests.byTime)if(e.ts>=r&&e.ts<n){const r=d(t,s,e);r&&a.push(r)}for(const e of[...a]){if(!e.rawRequest)continue;const t=e.rawRequest.args.data.redirects;if(!t.length)continue;const r=[];for(const n of t){const t=structuredClone(e);t.networkRequestTime=n.ts/1e3,t.rendererStartTime=t.networkRequestTime,t.networkEndTime=(n.ts+n.dur)/1e3,t.responseHeadersEndTime=t.networkEndTime,t.timing={requestTime:t.networkRequestTime/1e3,receiveHeadersStart:t.responseHeadersEndTime,receiveHeadersEnd:t.responseHeadersEndTime,proxyStart:-1,proxyEnd:-1,dnsStart:-1,dnsEnd:-1,connectStart:-1,connectEnd:-1,sslStart:-1,sslEnd:-1,sendStart:-1,sendEnd:-1,workerStart:-1,workerReady:-1,workerFetchStart:-1,workerRespondWithSettled:-1,pushStart:-1,pushEnd:-1},t.url=n.url,t.parsedURL=l(n.url),t.statusCode=302,t.resourceType=void 0,t.transferSize=400,r.push(t),a.push(t)}r.push(e);for(let e=0;e<r.length;e++){const t=r[e];e>0&&(t.redirectSource=r[e-1],t.redirects=r.slice(0,e)),e!==r.length-1&&(t.redirectDestination=r[e+1])}for(let e=1;e<r.length;e++)r[e].requestId=`${r[e-1].requestId}:redirect`}return function(e){const t=new Map;for(const r of e){const e=t.get(r.url)||[];e.push(r),t.set(r.url,e)}for(const r of e){const e=g(r,t);e&&(r.initiatorRequest=e)}}(a),a.sort(((e,t)=>e.rendererStartTime-t.rendererStartTime))}function u(e,t,r,n){const a=function(e,t){const r=t.Meta,n=r.mainFrameNavigations.length?new Set(r.mainFrameNavigations.map((e=>e.pid))):r.topLevelRendererIds,s=new Map;for(const e of n){const t=r.threadsInProcess.get(e)??[];let n=!1;for(const[r,a]of t)if("CrRendererMain"===a.args.name){s.set(e,r),n=!0;break}if(!n)for(const[r,a]of t)if("CrBrowserMain"===a.args.name){s.set(e,r),n=!0;break}}return e.traceEvents.filter((e=>s.get(e.pid)===e.tid))}(t,r);if(!n){n={requestedUrl:e[0].url,mainDocumentUrl:""};let t=e[0];for(;t.redirectDestination;)t=t.redirectDestination;n.mainDocumentUrl=t.url}return s.Graph.PageDependencyGraph.createGraph(a,e,n)}var f=Object.freeze({__proto__:null,createGraph:u,createNetworkRequests:h,createProcessedNavigation:c});class m extends Event{data;static eventName="traceparseprogress";constructor(e,t={bubbles:!0}){super(m.eventName,t),this.data=e}}function p(e,t){return.8===t?e*(.8-.2)+.2:e*t}class v extends EventTarget{#e;#t="IDLE";#r=i.Configuration.defaults();#n=null;#s=null;static createWithAllHandlers(){return new v(t.ModelHandlers,i.Configuration.defaults())}static getInsightRunners(){return{...n.Models}}constructor(e,r){super(),this.#a(e),this.#e={Meta:t.ModelHandlers.Meta,...e},r&&(this.#r=r),this.#i()}#i(){for(const e of Object.values(this.#e))"handleUserConfig"in e&&e.handleUserConfig&&e.handleUserConfig(this.#r)}#a(e){if(Object.keys(e).length===Object.keys(t.ModelHandlers).length)return;const r=new Set;for(const[t,n]of Object.entries(e)){r.add(t);const e="deps"in n?n.deps():[];for(const t of e)r.add(t)}const n=new Set(Object.keys(e));r.delete("Meta");for(const e of r)if(!n.has(e))throw new Error(`Required handler ${e} not provided.`)}reset(){if("PARSING"===this.#t)throw new Error("Trace processor can't reset while parsing.");const e=Object.values(this.#e);for(const t of e)t.reset();this.#n=null,this.#s=null,this.#t="IDLE"}async parse(e,t){if("IDLE"!==this.#t)throw new Error(`Trace processor can't start parsing when not idle. Current state: ${this.#t}`);t.logger?.start("total");try{this.#t="PARSING",t.logger?.start("parse"),await this.#o(e,t),t.logger?.end("parse"),this.#n&&!t.isCPUProfile&&(t.logger?.start("insights"),this.#c(this.#n,e,t),t.logger?.end("insights")),this.#t="FINISHED_PARSING"}catch(e){throw this.#t="ERRORED_WHILE_PARSING",e}finally{t.logger?.end("total")}}async#o(e,t){const r=[...C(this.#e).entries()];for(const[,e]of r)e.reset();t.logger?.start("parse:handleEvent");for(let t=0;t<e.length;++t){if(t%5e4==0&&t){const r=p(t/e.length,.2);this.dispatchEvent(new m({percent:r})),await new Promise((e=>setTimeout(e,0)))}const n=e[t];for(let e=0;e<r.length;++e){const[,t]=r[e];t.handleEvent(n)}}t.logger?.end("parse:handleEvent");for(let e=0;e<r.length;e++){const[n,s]=r[e];s.finalize&&(t.logger?.start(`parse:${n}:finalize`),await new Promise((e=>setTimeout(e,0))),await s.finalize(t),t.logger?.end(`parse:${n}:finalize`));const a=p(e/r.length,.8);this.dispatchEvent(new m({percent:a}))}const n=(e,t=!0)=>{if(e instanceof Map)return new Map(e);if(e instanceof Set)return new Set(e);if(Array.isArray(e))return[...e];if("object"==typeof e&&e&&t){const t={};for(const[r,s]of Object.entries(e))t[r]=n(s,!1);return t}return e};t.logger?.start("parse:clone");const s={};for(const[e,t]of Object.entries(this.#e)){const r=n(t.data());Object.assign(s,{[e]:r})}t.logger?.end("parse:clone"),this.dispatchEvent(new m({percent:1})),this.#n=s}get parsedTrace(){return"FINISHED_PARSING"!==this.#t?null:this.#n}get insights(){return"FINISHED_PARSING"!==this.#t?null:this.#s}#l(e,t,r,n,a){if(!e.NetworkRequests||!e.Workers||!e.PageLoadMetrics)return;if(!e.NetworkRequests.byTime.length)throw new s.Core.LanternError("No network requests found in trace");const i=e.Meta.navigationsByFrameId.get(r),o=i?.findIndex((e=>e.args.data?.navigationId===n));if(!i||void 0===o||-1===o)throw new s.Core.LanternError("Could not find navigation start");const l=i[o].ts,d=o+1<i.length?i[o+1].ts:Number.POSITIVE_INFINITY,g={traceEvents:t.filter((e=>e.ts>=l&&e.ts<d))},f=h(g,e,l,d),m=u(f,g,e),p=c(e,r,n),v=s.Core.NetworkAnalyzer.analyze(f);if(!v)return;const C={networkAnalysis:v,throttlingMethod:"provided",...a.lanternSettings},T=s.Simulation.Simulator.createSimulator(C),w={graph:m,simulator:T,processedNavigation:p},y=s.Metrics.FirstContentfulPaint.compute(w),I=s.Metrics.LargestContentfulPaint.compute(w,{fcpResult:y}),S=s.Metrics.Interactive.compute(w,{lcpResult:I});return{graph:m,simulator:T,metrics:{firstContentfulPaint:y,interactive:S,largestContentfulPaint:I,totalBlockingTime:s.Metrics.TotalBlockingTime.compute(w,{fcpResult:y,interactiveResult:S})}}}sortInsightSet(e,t,s){const a=n.Common.calculateMetricWeightsForSorting(t,s),o=n.Common.getLCP(e,t.id)?.value,c=o?r.Timing.microToMilli(o):i.Timing.Milli(0),l=n.Common.getCLS(e,t.id).value,d=n.Common.getINP(e,t.id)?.value,g=d?r.Timing.microToMilli(d):i.Timing.Milli(200),h=void 0!==c?n.Common.evaluateLCPMetricScore(c):void 0,u=n.Common.evaluateINPMetricScore(g),f=n.Common.evaluateCLSMetricScore(l),m=new Map;for(const[e,r]of Object.entries(t.model)){const t=r.metricSavings?.LCP??0,s=r.metricSavings?.INP??0,i=r.metricSavings?.CLS??0,o=void 0!==c?Math.max(0,c-t):void 0,d=Math.max(0,g-s),p=Math.max(0,l-i);let v=0;a.lcp&&t&&void 0!==h&&void 0!==o&&(v+=a.lcp*(n.Common.evaluateLCPMetricScore(o)-h)),a.inp&&s&&void 0!==u&&(v+=a.inp*(n.Common.evaluateINPMetricScore(d)-u)),a.cls&&i&&void 0!==f&&(v+=a.cls*(n.Common.evaluateCLSMetricScore(p)-f)),m.set(e,v)}const p=Object.keys({InteractionToNextPaint:null,LCPPhases:null,LCPDiscovery:null,CLSCulprits:null,RenderBlocking:null,NetworkDependencyTree:null,ImageDelivery:null,DocumentLatency:null,FontDisplay:null,Viewport:null,DOMSize:null,ThirdParties:null,DuplicatedJavaScript:null,SlowCSSSelector:null,ForcedReflow:null,Cache:null,ModernHTTP:null,LegacyJavaScript:null}),v=Object.keys(t.model);v.sort(((e,t)=>{const r=p.indexOf(e),n=p.indexOf(t);return r>=0&&n>=0?r-n:r>=0?-1:n>=0?1:0})),v.sort(((e,t)=>(m.get(t)??0)-(m.get(e)??0)));const C={};for(const e of v){const r=t.model[e];C[e]=r}t.model=C}#d(e,t,r,n){let s,a,o;r.navigation?(s=r.navigationId,a=t.Meta.finalDisplayUrlByNavigationId.get(r.navigationId)??t.Meta.mainFrameURL,o=r.navigation):(s=i.Events.NO_NAVIGATION,a=t.Meta.finalDisplayUrlByNavigationId.get("")??t.Meta.mainFrameURL);const c={};for(const[e,s]of Object.entries(v.getInsightRunners())){let a;try{n.logger?.start(`insights:${e}`),a=s.generateInsight(t,r),a.frameId=r.frameId;const i=r.navigation?.args.data?.navigationId;i&&(a.navigationId=i)}catch(e){a=e}finally{n.logger?.end(`insights:${e}`)}Object.assign(c,{[e]:a})}let l;try{l=new URL(a)}catch{return}const d={id:s,url:l,navigation:o,frameId:r.frameId,bounds:r.bounds,model:c};e.set(d.id,d),this.sortInsightSet(e,d,n.metadata??null)}#c(e,t,n){this.#s=new Map;const a=e.Meta.mainFrameNavigations.filter((e=>e.args.frame&&e.args.data?.navigationId));if(a.length){const t=r.Timing.traceWindowFromMicroSeconds(e.Meta.traceBounds.min,a[0].ts),s=r.Timing.milliToMicro(50);if(t.range>s){const r={bounds:t,frameId:e.Meta.mainFrameId};this.#d(this.#s,e,r,n)}}else{const t={bounds:e.Meta.traceBounds,frameId:e.Meta.mainFrameId};this.#d(this.#s,e,t,n)}for(const[i,o]of a.entries()){const c=o.args.frame,l=o.args.data?.navigationId;let d;try{n.logger?.start("insights:createLanternContext"),d=this.#l(e,t,c,l,n)}catch(e){const t=["mainDocumentRequest not found","missing metric scores for main frame","missing metric: FCP","missing metric: LCP","No network requests found in trace","Trace is too old"];e instanceof s.Core.LanternError&&t.some((t=>e.message===t))||console.error(e)}finally{n.logger?.end("insights:createLanternContext")}const g=o.ts,h=i+1<a.length?a[i+1].ts:e.Meta.traceBounds.max,u={bounds:r.Timing.traceWindowFromMicroSeconds(g,h),frameId:c,navigation:o,navigationId:l,lantern:d};this.#d(this.#s,e,u,n)}}}function C(e){const t=new Map,r=new Set,n=s=>{if(t.has(s))return;if(r.has(s)){let e="";for(const t of r)(e||t===s)&&(e+=`${t}->`);throw e+=s,new Error(`Found dependency cycle in trace event handlers: ${e}`)}r.add(s);const a=e[s];if(!a)return;const i=a.deps?.();i&&i.forEach(n),t.set(s,a)};for(const t of Object.keys(e))n(t);return t}var T=Object.freeze({__proto__:null,TraceParseProgressEvent:m,TraceProcessor:v,sortHandlers:C});class w extends EventTarget{#g=[];#h=[];#u=new Map;#f=[];#m=0;#p;#v=i.Configuration.defaults();static createWithAllHandlers(e){return new w(t.ModelHandlers,e)}static createWithSubsetOfHandlers(e,t){return new w(e,t)}constructor(e,t){super(),t&&(this.#v=t),this.#p=new v(e,this.#v)}async parse(e,t){const n=t?.metadata||{},s=t?.isFreshRecording||!1,a="CPUProfile"===n?.dataOrigin,i=e=>{const{data:t}=e;this.dispatchEvent(new y({type:"PROGRESS_UPDATE",data:t}))};this.#p.addEventListener(m.eventName,i);const o={traceEvents:e,metadata:n,parsedTrace:null,traceInsights:null};try{const i=r.SyntheticEvents.SyntheticEventsManager.createAndActivate(e);await this.#p.parse(e,{isFreshRecording:s,isCPUProfile:a,metadata:n,resolveSourceMap:t?.resolveSourceMap}),this.#C(o,this.#p.parsedTrace,this.#p.insights),this.#g.push(o),this.#h.push(i)}catch(e){throw e}finally{this.#p.removeEventListener(m.eventName,i),this.dispatchEvent(new y({type:"COMPLETE",data:"done"}))}}#C(e,t,n){e.parsedTrace=t,e.traceInsights=n,this.#m++;let s=`Trace ${this.#m}`,i=null;if(e.parsedTrace&&(i=r.Trace.extractOriginFromTrace(e.parsedTrace.Meta.mainFrameURL),i)){const e=a.MapUtilities.getWithDefault(this.#u,i,(()=>1));s=`${i} (${e})`,this.#u.set(i,e+1)}this.#f.push(s)}lastTraceIndex(){return this.size()-1}parsedTrace(e=this.#g.length-1){return this.#g.at(e)?.parsedTrace??null}traceInsights(e=this.#g.length-1){return this.#g.at(e)?.traceInsights??null}metadata(e=this.#g.length-1){return this.#g.at(e)?.metadata??null}overrideModifications(e,t){this.#g[e]&&(this.#g[e].metadata.modifications=t)}rawTraceEvents(e=this.#g.length-1){return this.#g.at(e)?.traceEvents??null}syntheticTraceEventsManager(e=this.#g.length-1){return this.#h.at(e)??null}size(){return this.#g.length}deleteTraceByIndex(e){this.#g.splice(e,1),this.#f.splice(e,1)}getRecordingsAvailable(){return this.#f}resetProcessor(){this.#p.reset()}}class y extends Event{data;static eventName="modelupdate";constructor(e){super(y.eventName),this.data=e}}var I=Object.freeze({__proto__:null,Model:w,ModelUpdateEvent:y,isModelUpdateDataComplete:function(e){return"COMPLETE"===e.type}});class S extends o.SDKModel.SDKModel{#T;#w;#y;#I;constructor(e){super(e),this.#T=e.tracingAgent(),e.registerTracingDispatcher(new M(this)),this.#w=null,this.#y=0}bufferUsage(e,t,r){this.#w&&this.#w.tracingBufferUsage(e||r||0)}eventsCollected(e){if(!this.#w)return;this.#w.traceEventsCollected(e),this.#y+=e.length;const t=Math.min(this.#y/9e5+.15,.9);this.#w.eventsRetrievalProgress(t)}tracingComplete(){this.#y=0,this.#w&&(this.#w.tracingComplete(),this.#w=null),this.#I=!1}async reset(){this.#w&&await this.#T.invoke_end(),this.#y=0,this.#w=null,this.#I=!1}async start(e,t,r){if(this.#w)throw new Error("Tracing is already started");this.#w=e;const n={bufferUsageReportingInterval:500,categories:t,options:r,transferMode:"ReportEvents"},s=await this.#T.invoke_start(n);return s.getError()&&(this.#w=null),s}stop(){if(!this.#w)throw new Error("Tracing is not started");if(this.#I)throw new Error("Tracing is already being stopped");this.#I=!0,this.#T.invoke_end()}rnPrepareForTraceCapturedInBackground(e){this.#w=e,this.#I=!0}}class M{#S;constructor(e){this.#S=e}bufferUsage({value:e,eventCount:t,percentFull:r}){this.#S.bufferUsage(e,t,r)}dataCollected({value:e}){this.#S.eventsCollected(e)}tracingComplete(){this.#S.tracingComplete()}}o.SDKModel.SDKModel.register(S,{capabilities:128,autostart:!1});var E=Object.freeze({__proto__:null,TracingManager:S});export{f as LanternComputationData,T as Processor,I as TraceModel,E as TracingManager};