@buoy-gg/network 7.0.63 → 7.0.64
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/README.md +4 -0
- package/lib/commonjs/network/utils/networkEventStore.js +1 -1
- package/lib/commonjs/network/utils/networkListener.js +4 -4
- package/lib/commonjs/network/utils/networkSavedStore.js +2 -2
- package/lib/module/network/utils/networkEventStore.js +1 -1
- package/lib/module/network/utils/networkListener.js +4 -4
- package/lib/module/network/utils/networkSavedStore.js +2 -2
- package/lib/typescript/network/utils/networkEventStore.d.ts +1 -0
- package/lib/web/index.mjs +45 -45
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -12,6 +12,8 @@ Inspect HTTP requests captured through your React Native app's global `fetch` an
|
|
|
12
12
|
|
|
13
13
|
</div>
|
|
14
14
|
|
|
15
|
+
Buoy hides its own cloud settings calls from the list.
|
|
16
|
+
|
|
15
17
|
## Install
|
|
16
18
|
|
|
17
19
|
```bash
|
|
@@ -25,3 +27,5 @@ The [Network guide](https://buoy.gg/buoy/latest/docs/tools/network) covers setup
|
|
|
25
27
|
---
|
|
26
28
|
|
|
27
29
|
<sub>Part of <a href="https://buoy.gg">Buoy</a>, developer tools that live inside your app. Proprietary software. © Buoy LLC. <a href="https://buoy.gg/terms">Terms</a></sub>
|
|
30
|
+
|
|
31
|
+
Buoy keeps its own web calls out of this view. App calls still show when they use the same files.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.networkEventStore=void 0;var _sharedUi=require("@buoy-gg/shared-ui");var _extractOperationName=require("./extractOperationName");var _networkListener=require("./networkListener");var _networkSavedStore=require("./networkSavedStore");const BOOT_BUFFER_MAX=200;class NetworkEventStore extends _sharedUi.BaseEventStore{pendingRequests=new Map;rawListenerUnsubscribe=null;bootBuffer=[];bootBufferUnsubscribe=null;mirrorMode=false;constructor(){super({storeName:"network",maxEvents:500})}startBootCapture(){if((0,_sharedUi.getAccountAccess)().status==="locked")return;if(this.mirrorMode||this.bootBufferUnsubscribe||this.isCapturing()){return}const t=(0,_networkListener.networkListener)();if(!t.isActive){t.startListening()}this.bootBufferUnsubscribe=(0,_networkListener.addNetworkListener)(e=>{this.bootBuffer.push(e);if(this.bootBuffer.length>BOOT_BUFFER_MAX)this.bootBuffer.shift()})}takeBootBuffer(){if(this.bootBufferUnsubscribe){this.bootBufferUnsubscribe();this.bootBufferUnsubscribe=null}const t=this.bootBuffer;this.bootBuffer=[];return t}startCapturing(){const t=(0,_networkListener.networkListener)();if(!t.isActive){t.startListening()}for(const e of this.takeBootBuffer()){this.processNetworkEvent(e)}if(!this.rawListenerUnsubscribe){this.rawListenerUnsubscribe=(0,_networkListener.addNetworkListener)(e=>{this.processNetworkEvent(e)})}t.adoptEarlyRequests()}stopCapturing(){this.takeBootBuffer();if(this.rawListenerUnsubscribe){this.rawListenerUnsubscribe();this.rawListenerUnsubscribe=null}if((0,_networkListener.getNetworkListenerCount)()===0){(0,_networkListener.stopNetworkListener)()}}disableCapture(){this.mirrorMode=true;this.takeBootBuffer();if((0,_networkListener.getNetworkListenerCount)()===0){(0,_networkListener.stopNetworkListener)()}super.disableCapture()}isCapturing(){return this.rawListenerUnsubscribe!==null}ensureInterception(){if(!this.isCapturing())return;(0,_networkListener.networkListener)().startListening()}subscribeToEvents(t){const e=super.subscribeToEvents(t);this.ensureInterception();return e}processNetworkEvent(t){if((0,_sharedUi.getAccountAccess)().status==="locked")return;const{request:e}=t;if(t.type==="request"){if(this.events.some(u=>u.id===e.id))return;const r=e.params?`?${new URLSearchParams(e.params).toString()}`:"";const s=`${e.url}${r}`;let n;let o;if(e.client==="graphql"){const u=(0,_extractOperationName.extractOperationName)(e.data);n=u||void 0;if(e.data&&typeof e.data==="object"&&"variables"in e.data&&e.data.variables&&typeof e.data.variables==="object"){o=e.data.variables}}const a={id:e.id,method:e.method,url:s,host:this.extractHost(e.url),path:this.extractPath(e.url),query:r,timestamp:t.timestamp.getTime(),requestHeaders:e.headers||{},requestData:e.data,requestSize:this.getDataSize(e.data),responseHeaders:{},requestClient:e.client,operationName:n,graphqlVariables:o,override:t.override,condition:t.condition};this.pendingRequests.set(e.id,a);this.events=[a,...this.events].slice(0,this.maxEvents);this.notify(a);this.notifyArrayListeners()}else if(t.type==="request-body"){const r=this.events.find(n=>n.id===e.id);if(!r)return;const s={...r,requestData:e.data,requestSize:this.getDataSize(e.data)};if(e.client==="graphql"){s.operationName=(0,_extractOperationName.extractOperationName)(e.data)||void 0;const n=e.data?.variables;if(n&&typeof n==="object")s.graphqlVariables=n}this.events=this.events.map(n=>n.id===e.id?s:n);if(this.pendingRequests.has(e.id))this.pendingRequests.set(e.id,s);_networkSavedStore.networkSavedStore.syncFromLive(s);this.notify(s);this.notifyArrayListeners()}else if(t.type==="response"||t.type==="error"){const r=this.events.findIndex(s=>s.id===e.id);if(r!==-1){const s={...this.events[r],duration:t.duration,timings:t.timings};if(t.response){s.status=t.response.status;s.statusText=t.response.statusText;s.responseHeaders=t.response.headers||{};s.responseData=t.response.body;s.responseSize=t.response.size||0;s.responseType=t.response.headers?.["content-type"]}if(t.error){s.error=t.error.message;s.status=s.status||0}if(t.override)s.override=t.override;this.events=this.events.map((n,o)=>o===r?s:n);this.pendingRequests.delete(e.id);_networkSavedStore.networkSavedStore.syncFromLive(s);this.notify(s);this.notifyArrayListeners()}}}extractHost(t){try{const e=new URL(t);return e.hostname}catch{return""}}extractPath(t){try{const e=new URL(t);return e.pathname}catch{return t}}getDataSize(t){if(!t)return 0;if(typeof t==="string")return t.length;try{return JSON.stringify(t).length}catch{return 0}}getEventById(t){return this.events.find(e=>e.id===t)}clearEvents(){super.clearEvents();this.pendingRequests.clear()}onEvent(t,e=true){const r=this.subscribe(t);if(e&&this.events.length>0){const s=[...this.events].reverse();for(const n of s){try{t(n)}catch{}}}return r}getStats(){const t=this.events.length;const e=this.events.filter(i=>i.status&&i.status>=200&&i.status<300).length;const r=this.events.filter(i=>i.error||i.status&&i.status>=400).length;const s=this.events.filter(i=>!i.status&&!i.error).length;const n=this.events.filter(i=>i.duration).map(i=>i.duration);const o=n.length>0?n.reduce((i,c)=>i+c,0)/n.length:0;const a=this.events.reduce((i,c)=>i+(c.requestSize||0),0);const u=this.events.reduce((i,c)=>i+(c.responseSize||0),0);return{totalRequests:t,successfulRequests:e,failedRequests:r,pendingRequests:s,totalDataSent:a,totalDataReceived:u,averageDuration:Math.round(o)}}filterEvents(t){let e=[...this.events];if(t.method){e=e.filter(r=>r.method===t.method)}if(t.status){switch(t.status){case"success":e=e.filter(r=>r.status&&r.status>=200&&r.status<300);break;case"error":e=e.filter(r=>r.error||r.status&&r.status>=400);break;case"pending":e=e.filter(r=>!r.status&&!r.error);break}}if(t.searchText){const r=t.searchText.toLowerCase();e=e.filter(s=>s.url.toLowerCase().includes(r)||s.method.toLowerCase().includes(r)||s.error&&s.error.toLowerCase().includes(r))}if(t.host){e=e.filter(r=>r.host===t.host)}return e}}const networkEventStore=exports.networkEventStore=new NetworkEventStore;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.networkEventStore=void 0;var _sharedUi=require("@buoy-gg/shared-ui");var _extractOperationName=require("./extractOperationName");var _networkListener=require("./networkListener");var _networkSavedStore=require("./networkSavedStore");const BOOT_BUFFER_MAX=200;class NetworkEventStore extends _sharedUi.BaseEventStore{replaceEvents(t){super.replaceEvents(t.filter(e=>!(0,_sharedUi.isBuoyRequest)(e.url)))}pendingRequests=new Map;rawListenerUnsubscribe=null;bootBuffer=[];bootBufferUnsubscribe=null;mirrorMode=false;constructor(){super({storeName:"network",maxEvents:500})}startBootCapture(){if((0,_sharedUi.getAccountAccess)().status==="locked")return;if(this.mirrorMode||this.bootBufferUnsubscribe||this.isCapturing()){return}const t=(0,_networkListener.networkListener)();if(!t.isActive){t.startListening()}this.bootBufferUnsubscribe=(0,_networkListener.addNetworkListener)(e=>{this.bootBuffer.push(e);if(this.bootBuffer.length>BOOT_BUFFER_MAX)this.bootBuffer.shift()})}takeBootBuffer(){if(this.bootBufferUnsubscribe){this.bootBufferUnsubscribe();this.bootBufferUnsubscribe=null}const t=this.bootBuffer;this.bootBuffer=[];return t}startCapturing(){const t=(0,_networkListener.networkListener)();if(!t.isActive){t.startListening()}for(const e of this.takeBootBuffer()){this.processNetworkEvent(e)}if(!this.rawListenerUnsubscribe){this.rawListenerUnsubscribe=(0,_networkListener.addNetworkListener)(e=>{this.processNetworkEvent(e)})}t.adoptEarlyRequests()}stopCapturing(){this.takeBootBuffer();if(this.rawListenerUnsubscribe){this.rawListenerUnsubscribe();this.rawListenerUnsubscribe=null}if((0,_networkListener.getNetworkListenerCount)()===0){(0,_networkListener.stopNetworkListener)()}}disableCapture(){this.mirrorMode=true;this.takeBootBuffer();if((0,_networkListener.getNetworkListenerCount)()===0){(0,_networkListener.stopNetworkListener)()}super.disableCapture()}isCapturing(){return this.rawListenerUnsubscribe!==null}ensureInterception(){if(!this.isCapturing())return;(0,_networkListener.networkListener)().startListening()}subscribeToEvents(t){const e=super.subscribeToEvents(t);this.ensureInterception();return e}processNetworkEvent(t){if((0,_sharedUi.getAccountAccess)().status==="locked")return;const{request:e}=t;if((0,_sharedUi.isBuoyRequest)(e.url))return;if(t.type==="request"){if(this.events.some(u=>u.id===e.id))return;const r=e.params?`?${new URLSearchParams(e.params).toString()}`:"";const s=`${e.url}${r}`;let n;let o;if(e.client==="graphql"){const u=(0,_extractOperationName.extractOperationName)(e.data);n=u||void 0;if(e.data&&typeof e.data==="object"&&"variables"in e.data&&e.data.variables&&typeof e.data.variables==="object"){o=e.data.variables}}const a={id:e.id,method:e.method,url:s,host:this.extractHost(e.url),path:this.extractPath(e.url),query:r,timestamp:t.timestamp.getTime(),requestHeaders:e.headers||{},requestData:e.data,requestSize:this.getDataSize(e.data),responseHeaders:{},requestClient:e.client,operationName:n,graphqlVariables:o,override:t.override,condition:t.condition};this.pendingRequests.set(e.id,a);this.events=[a,...this.events].slice(0,this.maxEvents);this.notify(a);this.notifyArrayListeners()}else if(t.type==="request-body"){const r=this.events.find(n=>n.id===e.id);if(!r)return;const s={...r,requestData:e.data,requestSize:this.getDataSize(e.data)};if(e.client==="graphql"){s.operationName=(0,_extractOperationName.extractOperationName)(e.data)||void 0;const n=e.data?.variables;if(n&&typeof n==="object")s.graphqlVariables=n}this.events=this.events.map(n=>n.id===e.id?s:n);if(this.pendingRequests.has(e.id))this.pendingRequests.set(e.id,s);_networkSavedStore.networkSavedStore.syncFromLive(s);this.notify(s);this.notifyArrayListeners()}else if(t.type==="response"||t.type==="error"){const r=this.events.findIndex(s=>s.id===e.id);if(r!==-1){const s={...this.events[r],duration:t.duration,timings:t.timings};if(t.response){s.status=t.response.status;s.statusText=t.response.statusText;s.responseHeaders=t.response.headers||{};s.responseData=t.response.body;s.responseSize=t.response.size||0;s.responseType=t.response.headers?.["content-type"]}if(t.error){s.error=t.error.message;s.status=s.status||0}if(t.override)s.override=t.override;this.events=this.events.map((n,o)=>o===r?s:n);this.pendingRequests.delete(e.id);_networkSavedStore.networkSavedStore.syncFromLive(s);this.notify(s);this.notifyArrayListeners()}}}extractHost(t){try{const e=new URL(t);return e.hostname}catch{return""}}extractPath(t){try{const e=new URL(t);return e.pathname}catch{return t}}getDataSize(t){if(!t)return 0;if(typeof t==="string")return t.length;try{return JSON.stringify(t).length}catch{return 0}}getEventById(t){return this.events.find(e=>e.id===t)}clearEvents(){super.clearEvents();this.pendingRequests.clear()}onEvent(t,e=true){const r=this.subscribe(t);if(e&&this.events.length>0){const s=[...this.events].reverse();for(const n of s){try{t(n)}catch{}}}return r}getStats(){const t=this.events.length;const e=this.events.filter(i=>i.status&&i.status>=200&&i.status<300).length;const r=this.events.filter(i=>i.error||i.status&&i.status>=400).length;const s=this.events.filter(i=>!i.status&&!i.error).length;const n=this.events.filter(i=>i.duration).map(i=>i.duration);const o=n.length>0?n.reduce((i,c)=>i+c,0)/n.length:0;const a=this.events.reduce((i,c)=>i+(c.requestSize||0),0);const u=this.events.reduce((i,c)=>i+(c.responseSize||0),0);return{totalRequests:t,successfulRequests:e,failedRequests:r,pendingRequests:s,totalDataSent:a,totalDataReceived:u,averageDuration:Math.round(o)}}filterEvents(t){let e=[...this.events];if(t.method){e=e.filter(r=>r.method===t.method)}if(t.status){switch(t.status){case"success":e=e.filter(r=>r.status&&r.status>=200&&r.status<300);break;case"error":e=e.filter(r=>r.error||r.status&&r.status>=400);break;case"pending":e=e.filter(r=>!r.status&&!r.error);break}}if(t.searchText){const r=t.searchText.toLowerCase();e=e.filter(s=>s.url.toLowerCase().includes(r)||s.method.toLowerCase().includes(r)||s.error&&s.error.toLowerCase().includes(r))}if(t.host){e=e.filter(r=>r.host===t.host)}return e}}const networkEventStore=exports.networkEventStore=new NetworkEventStore;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.stopNetworkListener=exports.startNetworkListener=exports.removeAllNetworkListeners=exports.networkListener=exports.isNetworkListening=exports.isNetworkInterceptionLive=exports.getNetworkListenerCount=exports.addNetworkListener=exports.BUOY_XHR_INTERCEPTOR_FLAG=exports.BUOY_FETCH_INTERCEPTOR_FLAG=void 0;var _resolveRequestUrl=require("./resolveRequestUrl");var _requestId=require("./requestId");var _xhr=require("../conditions/xhr");var _store=require("../conditions/store");var _wait=require("../conditions/wait");var _engine=require("../overrides/engine");var _applyToXhr=require("../overrides/applyToXhr");var _applyToFetch=require("../overrides/applyToFetch");var _types=require("../overrides/types");var _httpCompletion=require("./httpCompletion");var _realNow=require("./realNow");let devOrigin;function injectedHeaders(
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.stopNetworkListener=exports.startNetworkListener=exports.removeAllNetworkListeners=exports.networkListener=exports.isNetworkListening=exports.isNetworkInterceptionLive=exports.getNetworkListenerCount=exports.addNetworkListener=exports.BUOY_XHR_INTERCEPTOR_FLAG=exports.BUOY_FETCH_INTERCEPTOR_FLAG=void 0;var _sharedUi=require("@buoy-gg/shared-ui");var _resolveRequestUrl=require("./resolveRequestUrl");var _requestId=require("./requestId");var _xhr=require("../conditions/xhr");var _store=require("../conditions/store");var _wait=require("../conditions/wait");var _engine=require("../overrides/engine");var _applyToXhr=require("../overrides/applyToXhr");var _applyToFetch=require("../overrides/applyToFetch");var _types=require("../overrides/types");var _httpCompletion=require("./httpCompletion");var _realNow=require("./realNow");let devOrigin;function injectedHeaders(R){const e=globalThis.__buoyHeaderInjectors;if(!e||e.length===0)return void 0;let t;for(const s of e){try{const c=s(R);if(c)t={...t,...c}}catch{}}return t}function devServerOrigin(){if(devOrigin!==void 0)return devOrigin;devOrigin=null;try{if(typeof __DEV__!=="undefined"&&!__DEV__)return devOrigin;const R=require("react-native");const e=R?.NativeModules?.SourceCode;const t=e?.getConstants?.().scriptURL??e?.scriptURL;if(typeof t==="string"&&/^https?:\/\//.test(t)){const s=new URL(t);devOrigin=`${s.protocol}//${s.host}`}}catch{devOrigin=null}return devOrigin}let insideFetchHandoff=false;function headersToRecord(R){const e={};if(!R)return e;if(typeof Headers!=="undefined"&&R instanceof Headers)R.forEach((t,s)=>{e[s]=t});else if(Array.isArray(R))for(const[t,s]of R)e[t]=s;else Object.assign(e,R);return e}const BUOY_FETCH_INTERCEPTOR_FLAG=exports.BUOY_FETCH_INTERCEPTOR_FLAG="__buoyNetworkFetchIntercepted";const BUOY_XHR_INTERCEPTOR_FLAG=exports.BUOY_XHR_INTERCEPTOR_FLAG="__buoyNetworkXhrIntercepted";const STREAMED_CONTENT_TYPES=["text/event-stream","application/x-ndjson","application/stream+json"];const STREAMING_PLACEHOLDER="[streaming\u2026]";let angularPageSeen=false;function isAngularPage(){if(angularPageSeen)return true;const R=globalThis.document;angularPageSeen=!!R?.querySelector?.("[ng-version]");return angularPageSeen}function isStreamedContentType(R){if(!R)return false;const e=R.toLowerCase();return STREAMED_CONTENT_TYPES.some(t=>e.includes(t))}const INTERNAL_HOSTS_KEY="__BUOY_INTERNAL_HOSTS__";function isInternalBuoyHost(R){const e=globalThis[INTERNAL_HOSTS_KEY];if(!(e instanceof Set)||e.size===0)return false;let t;try{t=new URL(R).host.toLowerCase()}catch{return false}for(const s of e){if(typeof s==="string"&&s&&t===s.toLowerCase())return true}return false}class NetworkListener{listeners=[];isListening=false;patchedFetch=null;patchedXHROpen=null;patchedXHRSend=null;patchedXHRSetRequestHeader=null;fetchGeneration=0;xhrGeneration=0;constructor(){this.originalFetch=globalThis.fetch;this.originalXHROpen=XMLHttpRequest.prototype.open;this.originalXHRSend=XMLHttpRequest.prototype.send;this.originalXHRSetRequestHeader=XMLHttpRequest.prototype.setRequestHeader}shouldIgnoreUrl(e){if((0,_sharedUi.isBuoyRequest)(e))return true;try{const t=new URL(e);if(t.hostname==="keygen.sh"||t.hostname.endsWith(".keygen.sh"))return true;if((t.hostname==="buoy.gg"||t.hostname==="www.buoy.gg")&&(t.pathname.startsWith("/api/license")||t.pathname.startsWith("/api/settings/")))return true;const s=t.hostname==="localhost"||t.hostname==="127.0.0.1"||t.hostname==="10.0.2.2";if(s&&["8081","8802"].includes(t.port))return true;const c=devServerOrigin();if(c&&`${t.protocol}//${t.host}`===c)return true}catch{return false}return isInternalBuoyHost(e)}emit(e){this.listeners.forEach(t=>{try{t(e)}catch(s){}})}parseUrl(e){let t=null;const s=e.indexOf("?");if(s>-1){t={};e.substring(s+1).split("&").forEach(c=>{const[a,n]=c.split("=");if(a&&n!==void 0){t[a]=decodeURIComponent(n.replace(/\+/g," "))}})}return{url:s>-1?e.substring(0,s):e,params:t}}async readStreamedBody(e,t=256*1024){const s=e.body;if(!s||typeof s.getReader!=="function"){const f=await e.text();return f.length>t?{body:`${f.slice(0,t)}
|
|
2
2
|
|
|
3
|
-
... [truncated]`,size:f.length}:{body:f,size:f.length}}const c=s.getReader();const a=new TextDecoder;let n="";let l=0;let
|
|
3
|
+
... [truncated]`,size:f.length}:{body:f,size:f.length}}const c=s.getReader();const a=new TextDecoder;let n="";let l=0;let m=false;try{for(;;){const{done:f,value:i}=await c.read();if(f)break;l+=i?.byteLength??0;if(!m){n+=a.decode(i,{stream:true});if(l>=t){n=`${n.slice(0,t)}
|
|
4
4
|
|
|
5
|
-
... [truncated]`;
|
|
5
|
+
... [truncated]`;m=true;break}}}if(!m)n+=a.decode()}finally{try{void Promise.resolve(c.cancel()).catch(()=>{})}catch{}try{c.releaseLock()}catch{}}return{body:n,size:l}}async processResponseBody(e,t=1024*1024){try{const s=e.headers.get("content-length");if(s){const n=parseInt(s,10);if(!isNaN(n)&&n>t){return{body:`[Response too large: ${this.formatBytes(n)}]`,size:n,truncated:true}}}const c=await e.text();const a=c.length;if(a>t){const n=c.substring(0,t);const l=a-t;return{body:`${n}
|
|
6
6
|
|
|
7
|
-
... [truncated, ${this.formatBytes(l)} omitted]`,size:a,truncated:true}}try{return{body:JSON.parse(c),size:a,truncated:false}}catch{return{body:c,size:a,truncated:false}}}catch(s){return{body:"~~~ unable to read body ~~~",size:0,truncated:false}}}formatBytes(e){if(e===0)return"0 B";const t=1024;const s=["B","KB","MB","GB"];const c=Math.floor(Math.log(e)/Math.log(t));return`${Math.round(e/Math.pow(t,c)*100)/100} ${s[c]}`}handleXHRResponse(e,t,s,c,a,n,l,R,f=false,i="xhr",d,L){const g=R?(0,_realNow.realNow)()-R:0;const h=e._buoyTtfb;const _=h===void 0?void 0:{ttfb:h,download:Math.max(0,g-h)};if(f||e.status===0){this.emit({type:"error",timestamp:new Date,duration:g,request:{id:t||"unknown",url:s,method:c,headers:a,data:n,params:l||void 0,client:i},error:{message:f?"Request failed":"Network error or request aborted"},override:d,condition:L});return}let r;let p=0;try{const o=e.response;if(e.responseType==="json"&&o){r=o;p=JSON.stringify(o).length}else if(e.responseType===""||e.responseType==="text"){if(e.responseText){p=e.responseText.length;try{r=JSON.parse(e.responseText)}catch{r=e.responseText}}}else if(e.responseType==="arraybuffer"){if(o){try{const y=new TextDecoder("utf-8").decode(o);p=y.length;try{r=JSON.parse(y)}catch{r=y}}catch(y){r=`[arraybuffer response - ${o.byteLength||0} bytes]`;p=o.byteLength||0}}else{r=`[arraybuffer response - no data]`;p=0}}else if(e.responseType==="blob"){if(o instanceof Blob){r=`[blob response - ${o.size} bytes, type: ${o.type||"unknown"}]`;p=o.size}else if(o){try{r=typeof o==="string"?JSON.parse(o):o;p=JSON.stringify(r).length}catch{r=`[blob response - unable to parse]`;p=0}}else{r=`[blob response - no data]`;p=0}}else if(o){if(typeof o==="string"){r=o;p=o.length;try{r=JSON.parse(o)}catch{}}else if(typeof o==="object"){r=o;p=JSON.stringify(o).length}else{r=String(o);p=String(o).length}}}catch(o){r="~~~ unable to read body ~~~"}const m={};try{const o=e.getAllResponseHeaders();if(o){o.split("\r\n").forEach(y=>{if(y){const q=y.indexOf(": ");if(q>0){const u=y.substring(0,q).toLowerCase();const b=y.substring(q+2);m[u]=b}}})}}catch{}if((0,_httpCompletion.xhrCompletionKind)(e.status)==="response"){this.emit({type:"response",timestamp:new Date,duration:g,timings:_,request:{id:t||"unknown",url:s,method:c,headers:a,data:n,params:l||void 0,client:i},response:{status:e.status,statusText:(0,_httpCompletion.httpStatusText)(e.status,e.statusText),headers:m,body:r,size:p},override:d,condition:L})}else{this.emit({type:"error",timestamp:new Date,duration:g,request:{id:t||"unknown",url:s,method:c,headers:a,data:n,params:l||void 0,client:i},response:{status:e.status,statusText:e.statusText,headers:m,body:r,size:p},error:{message:"Network Error"},override:d,condition:L})}}isFetchInterceptionLive(){return globalThis.fetch[BUOY_FETCH_INTERCEPTOR_FLAG]===true}isXhrInterceptionLive(){return XMLHttpRequest.prototype.send[BUOY_XHR_INTERCEPTOR_FLAG]===true}isInterceptionLive(){return this.isFetchInterceptionLive()&&this.isXhrInterceptionLive()}startListening(){const e=this.isListening&&this.isFetchInterceptionLive();const t=this.isListening&&this.isXhrInterceptionLive();if(e&&t){return}if(!e){this.installFetchInterceptor()}if(!t){this.installXhrInterceptor()}this.isListening=true;if(__DEV__){}}installFetchInterceptor(){const e=this;const t=globalThis.fetch.bind(globalThis);this.originalFetch=globalThis.fetch;const s=++this.fetchGeneration;const c=async(a,n)=>{const l=(0,_resolveRequestUrl.resolveRequestUrl)(typeof a==="string"?a:a instanceof URL?a.href:a.url);if(s!==e.fetchGeneration){return t(a,n)}if(e.shouldIgnoreUrl(l)){return t(a,n)}const R=(0,_realNow.realNow)();const f=(0,_requestId.nextRequestId)("fetch");const i=typeof a==="object"&&"method"in a?a:void 0;const d=n?.method??i?.method??"GET";const L=n?.signal!==void 0?n.signal:i?.signal;(0,_wait.throwIfAborted)(L);const g=(0,_store.snapshotNetworkCondition)(l);const{url:h,params:_}=e.parseUrl(l);let r={};const p=n?.headers??i?.headers;if(p){if(p instanceof Headers){p.forEach((u,b)=>{r[b]=u})}else if(Array.isArray(p)){p.forEach(([u,b])=>{r[u]=b})}else{r={...p}}}Object.assign(r,injectedHeaders(l));let m;if(n?.body){if(typeof n.body==="string"){try{m=JSON.parse(n.body)}catch{m=n.body}}else{m=n.body}}const o=r["X-Request-Client"]||r["x-request-client"]||"fetch";const y=g?.profile!=="offline"&&(0,_applyToFetch.canSynthesizeResponse)()?(0,_engine.overrideForRequest)(l,d,r):null;const q=y?(0,_types.markForOutcome)(y):void 0;e.emit({type:"request",timestamp:new Date,request:{id:f||"unknown",url:h,method:d,headers:r,data:m,params:_||void 0,client:o},override:q,condition:g});if(n?.body===void 0&&i?.body&&!i.bodyUsed){try{const u=i.clone();void e.readStreamedBody(u).then(({body:b})=>{try{m=JSON.parse(b)}catch{m=b}e.emit({type:"request-body",timestamp:new Date,request:{id:f||"unknown",url:h,method:d,data:m,client:o}})}).catch(()=>{})}catch{}}try{if(g||y)await(0,_wait.waitBeforeDispatch)((g?.delayMs??0)+(y?.delayMs??0),L);(0,_wait.throwIfAborted)(L);if(g?.profile==="offline")throw new TypeError("Network request failed (Buoy Offline)");if(y?.kind==="fail")throw(0,_applyToFetch.synthesizeFetchError)(y);let u;if(y?.kind==="respond"){u=(0,_applyToFetch.synthesizeResponse)(l,y)}else{const v=insideFetchHandoff;insideFetchHandoff=true;let N;try{N=t(a,n)}finally{insideFetchHandoff=v}u=await N}const b=(0,_realNow.realNow)()-R;const H=typeof u.body?.getReader==="function"||isStreamedContentType(u.headers?.get?.("content-type"));const T=u.clone();const{body:I,size:S}=H?{body:STREAMING_PLACEHOLDER,size:0}:await e.processResponseBody(T);const E=(0,_realNow.realNow)()-R;const X=Math.max(0,E-b);const O=X>0?{ttfb:b,download:X}:void 0;const x={};u.headers.forEach((v,N)=>{x[N.toLowerCase()]=v});e.emit({type:"response",timestamp:new Date,duration:E,timings:O,request:{id:f||"unknown",url:h,method:d,headers:r,data:m,params:_||void 0,client:o},response:{status:u.status,statusText:u.statusText,headers:x,body:I,size:S},override:q,condition:g});if(H){void e.readStreamedBody(T).then(v=>{let N=v.body;if(u.headers?.get?.("content-type")?.includes("json")){try{N=JSON.parse(v.body)}catch{}}e.emit({type:"response",timestamp:new Date,duration:(0,_realNow.realNow)()-R,timings:O,request:{id:f||"unknown",url:h,method:d,headers:r,data:m,params:_||void 0,client:o},response:{status:u.status,statusText:u.statusText,headers:x,body:N,size:v.size},override:q,condition:g})}).catch(()=>{})}return u}catch(u){const b=(0,_realNow.realNow)()-R;e.emit({type:"error",timestamp:new Date,duration:b,request:{id:f||"unknown",url:h,method:d,headers:r,data:m,params:_||void 0,client:o},error:{message:u instanceof Error?u.message:"Network error",stack:u instanceof Error?u.stack:void 0},override:q,condition:g});throw u}};c[BUOY_FETCH_INTERCEPTOR_FLAG]=true;this.patchedFetch=c;globalThis.fetch=this.patchedFetch}installXhrInterceptor(){const e=this;const t=XMLHttpRequest.prototype.open;const s=XMLHttpRequest.prototype.send;const c=XMLHttpRequest.prototype.setRequestHeader;this.originalXHROpen=t;this.originalXHRSend=s;this.originalXHRSetRequestHeader=c;const a=++this.xhrGeneration;const n=new WeakMap;const l=function(i,d,L,g,h){const _=t.call(this,i,d,L??true,g,h);if(a===e.xhrGeneration){n.get(this)?.();const r=this;r._buoyRequestId=(0,_requestId.nextRequestId)("xhr");r._method=i;r._url=(0,_resolveRequestUrl.resolveRequestUrl)(d);r._buoyStartTime=(0,_realNow.realNow)();r._requestHeaders={}}return _};const R=function(i,d){const L=this;if(a===e.xhrGeneration&&L._requestHeaders){L._requestHeaders[i]=d}return c.call(this,i,d)};const f=function(i){if(a!==e.xhrGeneration||insideFetchHandoff){return s.call(this,i)}if((0,_applyToXhr.hasPendingStandardRequest)(this))throw new DOMException("The request has already been sent.","InvalidStateError");if(this.readyState!==1||this._sent){return s.call(this,i)}const d=this;const L=d._buoyRequestId;const g=d._method||"GET";const h=d._url||"";const _=(0,_realNow.realNow)();d._buoyStartTime=_;d._buoyTtfb=void 0;const r=d._requestHeaders||{};Object.assign(r,injectedHeaders(h));if(e.shouldIgnoreUrl(h)){return s.call(this,i)}const{url:p,params:m}=e.parseUrl(h);let o;if(i){if(typeof i==="string"){try{o=JSON.parse(i)}catch{o=i}}else{o=i}}const y=r["X-Request-Client"]||r["x-request-client"];const q=r["Accept"]||r["accept"]||"";const u=q.includes("application/json")&&q.includes("text/plain")&&q.includes("*/*");const b=y||(u?"axios":"xhr");const H=(0,_store.snapshotNetworkCondition)(h);const T=H?.profile==="offline"?null:(0,_engine.overrideForRequest)(h,g,r);const I=T?(0,_types.markForOutcome)(T):void 0;e.emit({type:"request",timestamp:new Date,request:{id:L||"unknown",url:p,method:g,headers:r,data:o,params:m||void 0,client:b},override:I,condition:H});let S=false;const E=(k=false)=>{if(S)return;S=true;e.handleXHRResponse(this,L||"unknown",p,g,r,o,m,_||0,k,b,I,H);X()};const X=()=>{n.delete(this);this.removeEventListener("load",O);this.removeEventListener("error",x);this.removeEventListener("abort",v);this.removeEventListener("readystatechange",N)};n.set(this,X);const O=()=>{E(false)};const x=()=>{E(true)};const v=()=>{E(true)};const N=()=>{if(this.readyState===2){const k=this;if(k._buoyTtfb===void 0&&k._buoyStartTime){k._buoyTtfb=(0,_realNow.realNow)()-k._buoyStartTime}}if(this.readyState===4&&!S){E(false)}};this.addEventListener("load",O);this.addEventListener("error",x);this.addEventListener("abort",v);this.addEventListener("readystatechange",N);if(H){(0,_xhr.runConditionXhr)(this,h,H,T,()=>s.call(this,i));return}if(T){const k=(0,_applyToXhr.runOverride)(this,h,T,()=>s.call(this,i));if(k)return}return s.call(this,i)};f[BUOY_XHR_INTERCEPTOR_FLAG]=true;this.patchedXHROpen=l;this.patchedXHRSend=f;this.patchedXHRSetRequestHeader=R;XMLHttpRequest.prototype.open=this.patchedXHROpen;XMLHttpRequest.prototype.send=this.patchedXHRSend;XMLHttpRequest.prototype.setRequestHeader=this.patchedXHRSetRequestHeader}stopListening(){if(!this.isListening){return}this.fetchGeneration++;this.xhrGeneration++;if(this.patchedFetch&&globalThis.fetch===this.patchedFetch){globalThis.fetch=this.originalFetch}if(this.patchedXHROpen&&XMLHttpRequest.prototype.open===this.patchedXHROpen){XMLHttpRequest.prototype.open=this.originalXHROpen}if(this.patchedXHRSend&&XMLHttpRequest.prototype.send===this.patchedXHRSend){XMLHttpRequest.prototype.send=this.originalXHRSend}if(this.patchedXHRSetRequestHeader&&XMLHttpRequest.prototype.setRequestHeader===this.patchedXHRSetRequestHeader){XMLHttpRequest.prototype.setRequestHeader=this.originalXHRSetRequestHeader}this.patchedFetch=null;this.patchedXHROpen=null;this.patchedXHRSend=null;this.patchedXHRSetRequestHeader=null;this.isListening=false;if(__DEV__){}}adoptEarlyRequests(){const e=globalThis.__BUOY_EARLY_NETWORK__;if(e?.version!==1)return;for(const t of e.adopt()){try{if(t.kind==="fetch")this.adoptEarlyFetch(t);else this.adoptEarlyXhr(t)}catch{}}}adoptEarlyFetch(e){const{input:t,init:s}=e;const c=typeof t==="object"&&"method"in t?t:void 0;const a=(0,_resolveRequestUrl.resolveRequestUrl)(typeof t==="string"?t:t instanceof URL?t.href:t.url);if(this.shouldIgnoreUrl(a))return;const n=(0,_requestId.nextRequestId)("fetch");const l=s?.method??c?.method??"GET";const{url:R,params:f}=this.parseUrl(a);const i=headersToRecord(s?.headers??c?.headers);let d=s?.body;if(typeof d==="string"){try{d=JSON.parse(d)}catch{}}const L=i["X-Request-Client"]||i["x-request-client"]||"fetch";const g=()=>({id:n,url:R,method:l,headers:i,data:d,params:f||void 0,client:L});this.emit({type:"request",timestamp:new Date(e.start),request:g()});if(e.requestCopy){void this.readStreamedBody(e.requestCopy).then(({body:h})=>{try{d=JSON.parse(h)}catch{d=h}this.emit({type:"request-body",timestamp:new Date,request:{id:n,url:R,method:l,data:d,client:L}})}).catch(()=>{})}void e.settled.then(async({response:h,clone:_,error:r,headersAt:p})=>{if(!h){this.emit({type:"error",timestamp:new Date,duration:p-e.start,request:g(),error:{message:r instanceof Error?r.message:"Network error",stack:r instanceof Error?r.stack:void 0}});return}const{body:m,size:o}=_?await this.processResponseBody(_):{body:STREAMING_PLACEHOLDER,size:0};const y=Math.max(0,(0,_realNow.realNow)()-e.start);const q=p-e.start;const u={};h.headers.forEach((b,H)=>{u[H.toLowerCase()]=b});this.emit({type:"response",timestamp:new Date,duration:y,timings:y>q?{ttfb:q,download:y-q}:void 0,request:g(),response:{status:h.status,statusText:h.statusText,headers:u,body:m,size:o}})})}adoptEarlyXhr(e){const t=(0,_resolveRequestUrl.resolveRequestUrl)(e.url);if(this.shouldIgnoreUrl(t))return;const s=(0,_requestId.nextRequestId)("xhr");const c=e.method.toUpperCase();const{url:a,params:n}=this.parseUrl(t);let l=e.body;if(typeof l==="string"){try{l=JSON.parse(l)}catch{}}const R=e.headers["X-Request-Client"]||e.headers["x-request-client"]||"xhr";this.emit({type:"request",timestamp:new Date(e.start),request:{id:s,url:a,method:c,headers:e.headers,data:l,params:n||void 0,client:R}});const f=e.xhr;const i=()=>{const d=(f._buoyEarlyEnd??(0,_realNow.realNow)())-e.start;this.handleXHRResponse(f,s,a,c,e.headers,l,n,(0,_realNow.realNow)()-d,false,R)};if(f.readyState===4)i();else f.addEventListener("loadend",i,{once:true})}addListener(e){this.listeners.push(e);return()=>{const t=this.listeners.indexOf(e);if(t>-1){this.listeners.splice(t,1)}}}removeAllListeners(){this.listeners=[]}get isActive(){return this.isListening}get listenerCount(){return this.listeners.length}}let _networkListener=null;const getNetworkListener=()=>{if(!_networkListener){_networkListener=new NetworkListener}return _networkListener};const networkListener=exports.networkListener=getNetworkListener;const startNetworkListener=()=>getNetworkListener().startListening();exports.startNetworkListener=startNetworkListener;const stopNetworkListener=()=>_networkListener?.stopListening();exports.stopNetworkListener=stopNetworkListener;const addNetworkListener=w=>getNetworkListener().addListener(w);exports.addNetworkListener=addNetworkListener;const removeAllNetworkListeners=()=>_networkListener?.removeAllListeners();exports.removeAllNetworkListeners=removeAllNetworkListeners;const isNetworkListening=()=>_networkListener?.isActive??false;exports.isNetworkListening=isNetworkListening;const getNetworkListenerCount=()=>_networkListener?.listenerCount??0;exports.getNetworkListenerCount=getNetworkListenerCount;const isNetworkInterceptionLive=()=>_networkListener?.isInterceptionLive()??false;exports.isNetworkInterceptionLive=isNetworkInterceptionLive;
|
|
7
|
+
... [truncated, ${this.formatBytes(l)} omitted]`,size:a,truncated:true}}try{return{body:JSON.parse(c),size:a,truncated:false}}catch{return{body:c,size:a,truncated:false}}}catch(s){return{body:"~~~ unable to read body ~~~",size:0,truncated:false}}}formatBytes(e){if(e===0)return"0 B";const t=1024;const s=["B","KB","MB","GB"];const c=Math.floor(Math.log(e)/Math.log(t));return`${Math.round(e/Math.pow(t,c)*100)/100} ${s[c]}`}handleXHRResponse(e,t,s,c,a,n,l,m,f=false,i="xhr",d,L){const g=m?(0,_realNow.realNow)()-m:0;const h=e._buoyTtfb;const _=h===void 0?void 0:{ttfb:h,download:Math.max(0,g-h)};if(f||e.status===0){this.emit({type:"error",timestamp:new Date,duration:g,request:{id:t||"unknown",url:s,method:c,headers:a,data:n,params:l||void 0,client:i},error:{message:f?"Request failed":"Network error or request aborted"},override:d,condition:L});return}let r;let p=0;try{const o=e.response;if(e.responseType==="json"&&o){r=o;p=JSON.stringify(o).length}else if(e.responseType===""||e.responseType==="text"){if(e.responseText){p=e.responseText.length;try{r=JSON.parse(e.responseText)}catch{r=e.responseText}}}else if(e.responseType==="arraybuffer"){if(o){try{const y=new TextDecoder("utf-8").decode(o);p=y.length;try{r=JSON.parse(y)}catch{r=y}}catch(y){r=`[arraybuffer response - ${o.byteLength||0} bytes]`;p=o.byteLength||0}}else{r=`[arraybuffer response - no data]`;p=0}}else if(e.responseType==="blob"){if(o instanceof Blob){r=`[blob response - ${o.size} bytes, type: ${o.type||"unknown"}]`;p=o.size}else if(o){try{r=typeof o==="string"?JSON.parse(o):o;p=JSON.stringify(r).length}catch{r=`[blob response - unable to parse]`;p=0}}else{r=`[blob response - no data]`;p=0}}else if(o){if(typeof o==="string"){r=o;p=o.length;try{r=JSON.parse(o)}catch{}}else if(typeof o==="object"){r=o;p=JSON.stringify(o).length}else{r=String(o);p=String(o).length}}}catch(o){r="~~~ unable to read body ~~~"}const w={};try{const o=e.getAllResponseHeaders();if(o){o.split("\r\n").forEach(y=>{if(y){const q=y.indexOf(": ");if(q>0){const u=y.substring(0,q).toLowerCase();const b=y.substring(q+2);w[u]=b}}})}}catch{}if((0,_httpCompletion.xhrCompletionKind)(e.status)==="response"){this.emit({type:"response",timestamp:new Date,duration:g,timings:_,request:{id:t||"unknown",url:s,method:c,headers:a,data:n,params:l||void 0,client:i},response:{status:e.status,statusText:(0,_httpCompletion.httpStatusText)(e.status,e.statusText),headers:w,body:r,size:p},override:d,condition:L})}else{this.emit({type:"error",timestamp:new Date,duration:g,request:{id:t||"unknown",url:s,method:c,headers:a,data:n,params:l||void 0,client:i},response:{status:e.status,statusText:e.statusText,headers:w,body:r,size:p},error:{message:"Network Error"},override:d,condition:L})}}isFetchInterceptionLive(){return globalThis.fetch[BUOY_FETCH_INTERCEPTOR_FLAG]===true}isXhrInterceptionLive(){return XMLHttpRequest.prototype.send[BUOY_XHR_INTERCEPTOR_FLAG]===true}isInterceptionLive(){return this.isFetchInterceptionLive()&&this.isXhrInterceptionLive()}startListening(){const e=this.isListening&&this.isFetchInterceptionLive();const t=this.isListening&&this.isXhrInterceptionLive();if(e&&t){return}if(!e){this.installFetchInterceptor()}if(!t){this.installXhrInterceptor()}this.isListening=true;if(__DEV__){}}installFetchInterceptor(){const e=this;const t=globalThis.fetch.bind(globalThis);this.originalFetch=globalThis.fetch;const s=++this.fetchGeneration;const c=async(a,n)=>{const l=(0,_resolveRequestUrl.resolveRequestUrl)(typeof a==="string"?a:a instanceof URL?a.href:a.url);if(s!==e.fetchGeneration){return t(a,n)}if(n?.__buoyInternal||e.shouldIgnoreUrl(l)){const u=insideFetchHandoff;insideFetchHandoff=true;try{return t(a,n)}finally{insideFetchHandoff=u}}const m=(0,_realNow.realNow)();const f=(0,_requestId.nextRequestId)("fetch");const i=typeof a==="object"&&"method"in a?a:void 0;const d=n?.method??i?.method??"GET";const L=n?.signal!==void 0?n.signal:i?.signal;(0,_wait.throwIfAborted)(L);const g=(0,_store.snapshotNetworkCondition)(l);const{url:h,params:_}=e.parseUrl(l);let r={};const p=n?.headers??i?.headers;if(p){if(p instanceof Headers){p.forEach((u,b)=>{r[b]=u})}else if(Array.isArray(p)){p.forEach(([u,b])=>{r[u]=b})}else{r={...p}}}Object.assign(r,injectedHeaders(l));let w;if(n?.body){if(typeof n.body==="string"){try{w=JSON.parse(n.body)}catch{w=n.body}}else{w=n.body}}const o=r["X-Request-Client"]||r["x-request-client"]||"fetch";const y=g?.profile!=="offline"&&(0,_applyToFetch.canSynthesizeResponse)()?(0,_engine.overrideForRequest)(l,d,r):null;const q=y?(0,_types.markForOutcome)(y):void 0;e.emit({type:"request",timestamp:new Date,request:{id:f||"unknown",url:h,method:d,headers:r,data:w,params:_||void 0,client:o},override:q,condition:g});if(n?.body===void 0&&i?.body&&!i.bodyUsed){try{const u=i.clone();void e.readStreamedBody(u).then(({body:b})=>{try{w=JSON.parse(b)}catch{w=b}e.emit({type:"request-body",timestamp:new Date,request:{id:f||"unknown",url:h,method:d,data:w,client:o}})}).catch(()=>{})}catch{}}try{if(g||y)await(0,_wait.waitBeforeDispatch)((g?.delayMs??0)+(y?.delayMs??0),L);(0,_wait.throwIfAborted)(L);if(g?.profile==="offline")throw new TypeError("Network request failed (Buoy Offline)");if(y?.kind==="fail")throw(0,_applyToFetch.synthesizeFetchError)(y);let u;if(y?.kind==="respond"){u=(0,_applyToFetch.synthesizeResponse)(l,y)}else{const N=insideFetchHandoff;insideFetchHandoff=true;let H;try{H=t(a,n)}finally{insideFetchHandoff=N}u=await H}const b=(0,_realNow.realNow)()-m;const T=typeof u.body?.getReader==="function"||isStreamedContentType(u.headers?.get?.("content-type"));const k=u.clone();const{body:I,size:x}=T?{body:STREAMING_PLACEHOLDER,size:0}:await e.processResponseBody(k);const E=(0,_realNow.realNow)()-m;const X=Math.max(0,E-b);const O=X>0?{ttfb:b,download:X}:void 0;const S={};u.headers.forEach((N,H)=>{S[H.toLowerCase()]=N});e.emit({type:"response",timestamp:new Date,duration:E,timings:O,request:{id:f||"unknown",url:h,method:d,headers:r,data:w,params:_||void 0,client:o},response:{status:u.status,statusText:u.statusText,headers:S,body:I,size:x},override:q,condition:g});if(T){const N=u.headers?.get?.("content-type");void e.readStreamedBody(k,isStreamedContentType(N)?void 0:1024*1024).then(H=>{let v=H.body;if(N?.includes("json")){try{v=JSON.parse(H.body)}catch{}}e.emit({type:"response",timestamp:new Date,duration:(0,_realNow.realNow)()-m,timings:O,request:{id:f||"unknown",url:h,method:d,headers:r,data:w,params:_||void 0,client:o},response:{status:u.status,statusText:u.statusText,headers:S,body:v,size:H.size},override:q,condition:g})}).catch(()=>{})}return u}catch(u){const b=(0,_realNow.realNow)()-m;e.emit({type:"error",timestamp:new Date,duration:b,request:{id:f||"unknown",url:h,method:d,headers:r,data:w,params:_||void 0,client:o},error:{message:u instanceof Error?u.message:"Network error",stack:u instanceof Error?u.stack:void 0},override:q,condition:g});throw u}};c[BUOY_FETCH_INTERCEPTOR_FLAG]=true;this.patchedFetch=c;globalThis.fetch=this.patchedFetch}installXhrInterceptor(){const e=this;const t=XMLHttpRequest.prototype.open;const s=XMLHttpRequest.prototype.send;const c=XMLHttpRequest.prototype.setRequestHeader;this.originalXHROpen=t;this.originalXHRSend=s;this.originalXHRSetRequestHeader=c;const a=++this.xhrGeneration;const n=new WeakMap;const l=function(i,d,L,g,h){const _=t.call(this,i,d,L??true,g,h);if(a===e.xhrGeneration){n.get(this)?.();const r=this;r._buoyRequestId=(0,_requestId.nextRequestId)("xhr");r._method=i;r._url=(0,_resolveRequestUrl.resolveRequestUrl)(d);r._buoyStartTime=(0,_realNow.realNow)();r._requestHeaders={}}return _};const m=function(i,d){const L=this;if(a===e.xhrGeneration&&L._requestHeaders){L._requestHeaders[i]=d}return c.call(this,i,d)};const f=function(i){if(a!==e.xhrGeneration||insideFetchHandoff){return s.call(this,i)}if((0,_applyToXhr.hasPendingStandardRequest)(this))throw new DOMException("The request has already been sent.","InvalidStateError");if(this.readyState!==1||this._sent){return s.call(this,i)}const d=this;const L=d._buoyRequestId;const g=d._method||"GET";const h=d._url||"";const _=(0,_realNow.realNow)();d._buoyStartTime=_;d._buoyTtfb=void 0;const r=d._requestHeaders||{};Object.assign(r,injectedHeaders(h));if(e.shouldIgnoreUrl(h)){return s.call(this,i)}const{url:p,params:w}=e.parseUrl(h);let o;if(i){if(typeof i==="string"){try{o=JSON.parse(i)}catch{o=i}}else{o=i}}const y=r["X-Request-Client"]||r["x-request-client"];const q=r["Accept"]||r["accept"]||"";const u=q.includes("application/json")&&q.includes("text/plain")&&q.includes("*/*")&&!isAngularPage();const b=y||(u?"axios":"xhr");const T=(0,_store.snapshotNetworkCondition)(h);const k=T?.profile==="offline"?null:(0,_engine.overrideForRequest)(h,g,r);const I=k?(0,_types.markForOutcome)(k):void 0;e.emit({type:"request",timestamp:new Date,request:{id:L||"unknown",url:p,method:g,headers:r,data:o,params:w||void 0,client:b},override:I,condition:T});let x=false;const E=(v=false)=>{if(x)return;x=true;e.handleXHRResponse(this,L||"unknown",p,g,r,o,w,_||0,v,b,I,T);X()};const X=()=>{n.delete(this);this.removeEventListener("load",O);this.removeEventListener("error",S);this.removeEventListener("abort",N);this.removeEventListener("readystatechange",H)};n.set(this,X);const O=()=>{E(false)};const S=()=>{E(true)};const N=()=>{E(true)};const H=()=>{if(this.readyState===2){const v=this;if(v._buoyTtfb===void 0&&v._buoyStartTime){v._buoyTtfb=(0,_realNow.realNow)()-v._buoyStartTime}}if(this.readyState===4&&!x){E(false)}};this.addEventListener("load",O);this.addEventListener("error",S);this.addEventListener("abort",N);this.addEventListener("readystatechange",H);if(T){(0,_xhr.runConditionXhr)(this,h,T,k,()=>s.call(this,i));return}if(k){const v=(0,_applyToXhr.runOverride)(this,h,k,()=>s.call(this,i));if(v)return}return s.call(this,i)};f[BUOY_XHR_INTERCEPTOR_FLAG]=true;this.patchedXHROpen=l;this.patchedXHRSend=f;this.patchedXHRSetRequestHeader=m;XMLHttpRequest.prototype.open=this.patchedXHROpen;XMLHttpRequest.prototype.send=this.patchedXHRSend;XMLHttpRequest.prototype.setRequestHeader=this.patchedXHRSetRequestHeader}stopListening(){if(!this.isListening){return}this.fetchGeneration++;this.xhrGeneration++;if(this.patchedFetch&&globalThis.fetch===this.patchedFetch){globalThis.fetch=this.originalFetch}if(this.patchedXHROpen&&XMLHttpRequest.prototype.open===this.patchedXHROpen){XMLHttpRequest.prototype.open=this.originalXHROpen}if(this.patchedXHRSend&&XMLHttpRequest.prototype.send===this.patchedXHRSend){XMLHttpRequest.prototype.send=this.originalXHRSend}if(this.patchedXHRSetRequestHeader&&XMLHttpRequest.prototype.setRequestHeader===this.patchedXHRSetRequestHeader){XMLHttpRequest.prototype.setRequestHeader=this.originalXHRSetRequestHeader}this.patchedFetch=null;this.patchedXHROpen=null;this.patchedXHRSend=null;this.patchedXHRSetRequestHeader=null;this.isListening=false;if(__DEV__){}}adoptEarlyRequests(){const e=globalThis.__BUOY_EARLY_NETWORK__;if(e?.version!==1)return;for(const t of e.adopt()){try{if(t.kind==="fetch")this.adoptEarlyFetch(t);else this.adoptEarlyXhr(t)}catch{}}}adoptEarlyFetch(e){const{input:t,init:s}=e;const c=typeof t==="object"&&"method"in t?t:void 0;const a=(0,_resolveRequestUrl.resolveRequestUrl)(typeof t==="string"?t:t instanceof URL?t.href:t.url);if(this.shouldIgnoreUrl(a))return;const n=(0,_requestId.nextRequestId)("fetch");const l=s?.method??c?.method??"GET";const{url:m,params:f}=this.parseUrl(a);const i=headersToRecord(s?.headers??c?.headers);let d=s?.body;if(typeof d==="string"){try{d=JSON.parse(d)}catch{}}const L=i["X-Request-Client"]||i["x-request-client"]||"fetch";const g=()=>({id:n,url:m,method:l,headers:i,data:d,params:f||void 0,client:L});this.emit({type:"request",timestamp:new Date(e.start),request:g()});if(e.requestCopy){void this.readStreamedBody(e.requestCopy).then(({body:h})=>{try{d=JSON.parse(h)}catch{d=h}this.emit({type:"request-body",timestamp:new Date,request:{id:n,url:m,method:l,data:d,client:L}})}).catch(()=>{})}void e.settled.then(async({response:h,clone:_,error:r,headersAt:p})=>{if(!h){this.emit({type:"error",timestamp:new Date,duration:p-e.start,request:g(),error:{message:r instanceof Error?r.message:"Network error",stack:r instanceof Error?r.stack:void 0}});return}const{body:w,size:o}=_?await this.processResponseBody(_):{body:STREAMING_PLACEHOLDER,size:0};const y=Math.max(0,(0,_realNow.realNow)()-e.start);const q=p-e.start;const u={};h.headers.forEach((b,T)=>{u[T.toLowerCase()]=b});this.emit({type:"response",timestamp:new Date,duration:y,timings:y>q?{ttfb:q,download:y-q}:void 0,request:g(),response:{status:h.status,statusText:h.statusText,headers:u,body:w,size:o}})})}adoptEarlyXhr(e){const t=(0,_resolveRequestUrl.resolveRequestUrl)(e.url);if(this.shouldIgnoreUrl(t))return;const s=(0,_requestId.nextRequestId)("xhr");const c=e.method.toUpperCase();const{url:a,params:n}=this.parseUrl(t);let l=e.body;if(typeof l==="string"){try{l=JSON.parse(l)}catch{}}const m=e.headers["X-Request-Client"]||e.headers["x-request-client"]||"xhr";this.emit({type:"request",timestamp:new Date(e.start),request:{id:s,url:a,method:c,headers:e.headers,data:l,params:n||void 0,client:m}});const f=e.xhr;const i=()=>{const d=(f._buoyEarlyEnd??(0,_realNow.realNow)())-e.start;this.handleXHRResponse(f,s,a,c,e.headers,l,n,(0,_realNow.realNow)()-d,false,m)};if(f.readyState===4)i();else f.addEventListener("loadend",i,{once:true})}addListener(e){this.listeners.push(e);return()=>{const t=this.listeners.indexOf(e);if(t>-1){this.listeners.splice(t,1)}}}removeAllListeners(){this.listeners=[]}get isActive(){return this.isListening}get listenerCount(){return this.listeners.length}}let _networkListener=null;const getNetworkListener=()=>{if(!_networkListener){_networkListener=new NetworkListener}return _networkListener};const networkListener=exports.networkListener=getNetworkListener;const startNetworkListener=()=>getNetworkListener().startListening();exports.startNetworkListener=startNetworkListener;const stopNetworkListener=()=>_networkListener?.stopListening();exports.stopNetworkListener=stopNetworkListener;const addNetworkListener=R=>getNetworkListener().addListener(R);exports.addNetworkListener=addNetworkListener;const removeAllNetworkListeners=()=>_networkListener?.removeAllListeners();exports.removeAllNetworkListeners=removeAllNetworkListeners;const isNetworkListening=()=>_networkListener?.isActive??false;exports.isNetworkListening=isNetworkListening;const getNetworkListenerCount=()=>_networkListener?.listenerCount??0;exports.getNetworkListenerCount=getNetworkListenerCount;const isNetworkInterceptionLive=()=>_networkListener?.isInterceptionLive()??false;exports.isNetworkInterceptionLive=isNetworkInterceptionLive;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.SESSION_ID=exports.MAX_SAVED=exports.MAX_PINNED=exports.FREE_TIER_SAVED_LIMIT=void 0;exports.flagsForEventId=flagsForEventId;exports.networkSavedStore=void 0;var _sharedUi=require("@buoy-gg/shared-ui");const SESSION_ID=exports.SESSION_ID=`${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`;const MAX_PINNED=exports.MAX_PINNED=25;const MAX_SAVED=exports.MAX_SAVED=50;const FREE_TIER_SAVED_LIMIT=exports.FREE_TIER_SAVED_LIMIT=_sharedUi.TIER_LIMITS["network.saved"].free;const BODY_LIMIT=16*1024;const TOTAL_BODY_BUDGET=512*1024;function isStorableEvent(n){if(!n||typeof n!=="object")return false;const e=n;return typeof e.id==="string"&&typeof e.url==="string"}const REMOTE_ECHO_GRACE_MS=800;function flagsForEventId(n,e){if(!e)return{pinned:false,saved:false};const t=n.pinnedLiveIds.has(e);const s=n.savedLiveIds.has(e);if(t||s)return{pinned:t,saved:s};const o=n.records.find(r=>r.event.id===e);return o?{pinned:o.pinned,saved:o.saved}:{pinned:false,saved:false}}const EMPTY_STATE={records:[],pinnedEvents:[],savedRecords:[],pinnedLiveIds:new Set,savedLiveIds:new Set};function truncateBody(n){if(n===void 0||n===null)return{value:n,truncated:false};if(typeof n==="string"){if(n.length<=BODY_LIMIT)return{value:n,truncated:false};return{value:`${n.slice(0,BODY_LIMIT)}
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.SESSION_ID=exports.MAX_SAVED=exports.MAX_PINNED=exports.FREE_TIER_SAVED_LIMIT=void 0;exports.flagsForEventId=flagsForEventId;exports.networkSavedStore=void 0;var _sharedUi=require("@buoy-gg/shared-ui");const SESSION_ID=exports.SESSION_ID=`${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`;const MAX_PINNED=exports.MAX_PINNED=25;const MAX_SAVED=exports.MAX_SAVED=50;const FREE_TIER_SAVED_LIMIT=exports.FREE_TIER_SAVED_LIMIT=_sharedUi.TIER_LIMITS["network.saved"].free;const BODY_LIMIT=16*1024;const TOTAL_BODY_BUDGET=512*1024;function isStorableEvent(n){if(!n||typeof n!=="object")return false;const e=n;return typeof e.id==="string"&&typeof e.url==="string"&&!(0,_sharedUi.isBuoyRequest)(e.url)}const REMOTE_ECHO_GRACE_MS=800;function flagsForEventId(n,e){if(!e)return{pinned:false,saved:false};const t=n.pinnedLiveIds.has(e);const s=n.savedLiveIds.has(e);if(t||s)return{pinned:t,saved:s};const o=n.records.find(r=>r.event.id===e);return o?{pinned:o.pinned,saved:o.saved}:{pinned:false,saved:false}}const EMPTY_STATE={records:[],pinnedEvents:[],savedRecords:[],pinnedLiveIds:new Set,savedLiveIds:new Set};function truncateBody(n){if(n===void 0||n===null)return{value:n,truncated:false};if(typeof n==="string"){if(n.length<=BODY_LIMIT)return{value:n,truncated:false};return{value:`${n.slice(0,BODY_LIMIT)}
|
|
2
2
|
|
|
3
3
|
\u2026 truncated by Buoy (body exceeded ${BODY_LIMIT} bytes)`,truncated:true}}try{const e=JSON.stringify(n);if(e===void 0)return{value:void 0,truncated:false};if(e.length<=BODY_LIMIT)return{value:n,truncated:false};return{value:`${e.slice(0,BODY_LIMIT)}
|
|
4
4
|
|
|
5
|
-
\u2026 truncated by Buoy (body exceeded ${BODY_LIMIT} bytes)`,truncated:true}}catch{return{value:"[unserializable body]",truncated:true}}}function snapshot(n){const e=truncateBody(n.requestData);const t=truncateBody(n.responseData);if(!e.truncated&&!t.truncated){return{event:{...n},bodyTruncated:false}}return{event:{...n,requestData:e.value,responseData:t.value},bodyTruncated:true}}function bodyBytes(n){let e=0;if(n.requestData!=null){e+=Math.min(n.requestSize??0,BODY_LIMIT)}if(n.responseData!=null){e+=Math.min(n.responseSize??0,BODY_LIMIT)}return e}function applyBodyBudget(n){let e=0;for(const r of n)e+=bodyBytes(r.event);if(e<=TOTAL_BODY_BUDGET)return n;const t=[...n].sort((r,i)=>{if(r.pinned!==i.pinned)return r.pinned?-1:1;return i.savedAt-r.savedAt});const s=new Set;let o=0;for(const r of t){const i=bodyBytes(r.event);if(o+i<=TOTAL_BODY_BUDGET){o+=i}else{s.add(r.key)}}if(s.size===0)return n;return n.map(r=>s.has(r.key)?{...r,event:{...r.event,requestData:void 0,responseData:void 0},bodyTruncated:true}:r)}function parseRecords(n){if(!Array.isArray(n))return[];const e=[];for(const t of n){if(!t||typeof t!=="object")continue;const s=t;if(typeof s.key!=="string")continue;if(!isStorableEvent(s.event))continue;if(!s.pinned&&!s.saved)continue;e.push({key:s.key,event:{...s.event,id:`saved:${s.key}`},pinned:!!s.pinned,saved:!!s.saved,savedAt:typeof s.savedAt==="number"?s.savedAt:0,sessionId:typeof s.sessionId==="string"?s.sessionId:"unknown",liveId:typeof s.liveId==="string"?s.liveId:"",bodyTruncated:!!s.bodyTruncated})}return e}class NetworkSavedStore{records=[];listeners=new Set;loaded=false;loadPromise=null;dirty=false;keyCounter=0;trackedLiveIds=new Set;state=EMPTY_STATE;remote=null;remoteEchoUntil=0;getState(){return this.state}enableRemoteMode(e){this.remote=e}disableRemoteMode(){this.remote=null}replaceRecords(e,t=false){if(!this.remote)return;if(!t&&Date.now()<this.remoteEchoUntil)return;this.records=e;this.rebuild();this.emit()}sessionMatches(e){return this.remote!==null||e.sessionId===SESSION_ID}getRecords(){return this.records}subscribe(e){this.listeners.add(e);void this.ensureLoaded();return()=>{this.listeners.delete(e)}}getEventById(e){for(const t of this.records){if(t.event.id===e)return t.event}return null}isPinned(e){return this.state.pinnedLiveIds.has(e)}isSaved(e){return this.state.savedLiveIds.has(e)}syncFromLive(e){if(this.trackedLiveIds.size===0)return;if(!this.trackedLiveIds.has(e.id))return;const t=this.records.findIndex(o=>this.sessionMatches(o)&&o.liveId===e.id);if(t===-1)return;const s=snapshot(e);this.commit(this.records.map((o,r)=>r===t?{...o,event:s.event,bodyTruncated:s.bodyTruncated}:o))}togglePin(e){return this.setFlag(e,"pinned")}toggleSave(e){return this.setFlag(e,"saved")}remove(e){if(!this.records.some(t=>t.key===e))return;this.remote?.removeRecord(e);this.commit(this.records.filter(t=>t.key!==e))}clearSaved(){if(!this.records.some(e=>e.saved))return;this.remote?.clearSaved();this.commit(this.records.filter(e=>e.pinned).map(e=>({...e,saved:false})))}clearPinned(){if(!this.records.some(e=>e.pinned))return;this.remote?.clearPinned();this.commit(this.records.filter(e=>e.saved).map(e=>({...e,pinned:false})))}setFlag(e,t){if(!isStorableEvent(e))return{ok:false,reason:"invalid-event"};const s=this.findRecordFor(e);if(this.remote){const d=s?!s[t]:true;if(t==="pinned")this.remote.setPinned(e.id,d);else this.remote.setSaved(e.id,d);this.remoteEchoUntil=Date.now()+REMOTE_ECHO_GRACE_MS}if(s){const d=!s[t];if(d&&!this.hasRoomFor(t,s.key)){return{ok:false,reason:t==="pinned"?"pin-cap":"saved-cap"}}const c={...s,[t]:d};this.commit(c.pinned||c.saved?this.records.map(a=>a.key===s.key?c:a):this.records.filter(a=>a.key!==s.key));return{ok:true,active:d}}if(!this.hasRoomFor(t,null)){return{ok:false,reason:t==="pinned"?"pin-cap":"saved-cap"}}const o=Date.now();const r=snapshot(e);const i={key:`${SESSION_ID}_${++this.keyCounter}`,event:r.event,pinned:t==="pinned",saved:t==="saved",savedAt:o,sessionId:SESSION_ID,liveId:e.id,bodyTruncated:r.bodyTruncated};this.commit(this.evictIfNeeded([i,...this.records]));return{ok:true,active:true}}findRecordFor(e){return this.records.find(t=>t.event.id===e.id||this.sessionMatches(t)&&t.liveId===e.id)}hasRoomFor(e,t){const s=e==="pinned"?MAX_PINNED:MAX_SAVED;const o=this.records.filter(r=>r[e]&&r.key!==t).length;return o<s}evictIfNeeded(e){const t=e.filter(r=>r.saved);if(t.length<=MAX_SAVED)return e;const s=t.filter(r=>!r.pinned).sort((r,i)=>r.savedAt-i.savedAt).slice(0,t.length-MAX_SAVED);if(s.length===0)return e;const o=new Set(s.map(r=>r.key));return e.filter(r=>!o.has(r.key))}ensureLoaded(){if(this.remote)return Promise.resolve();if(this.loaded)return Promise.resolve();if(this.loadPromise)return this.loadPromise;this.loadPromise=(async()=>{try{const e=await _sharedUi.persistentStorage.getItem(_sharedUi.devToolsStorageKeys.network.saved());if(e&&!this.dirty){this.records=parseRecords(JSON.parse(e));this.rebuild()}}catch{}finally{this.loaded=true;this.emit()}})();return this.loadPromise}persist(){if(this.remote)return;_sharedUi.persistentStorage.setItem(_sharedUi.devToolsStorageKeys.network.saved(),JSON.stringify(this.records)).catch(()=>{})}commit(e){this.dirty=true;this.records=applyBodyBudget(e);this.rebuild();this.emit();this.persist()}rebuild(){const e=[];const t=[];const s=new Set;const o=new Set;const r=new Set;for(const i of this.records){if(i.pinned)e.push(i);if(i.saved)t.push(i);if(!this.sessionMatches(i)||!i.liveId)continue;r.add(i.liveId);if(i.pinned)s.add(i.liveId);if(i.saved)o.add(i.liveId)}this.trackedLiveIds=r;this.state={records:this.records,pinnedEvents:e.map(i=>i.event),savedRecords:t,pinnedLiveIds:s,savedLiveIds:o}}emit(){this.listeners.forEach(e=>e())}}const networkSavedStore=exports.networkSavedStore=new NetworkSavedStore;
|
|
5
|
+
\u2026 truncated by Buoy (body exceeded ${BODY_LIMIT} bytes)`,truncated:true}}catch{return{value:"[unserializable body]",truncated:true}}}function snapshot(n){const e=truncateBody(n.requestData);const t=truncateBody(n.responseData);if(!e.truncated&&!t.truncated){return{event:{...n},bodyTruncated:false}}return{event:{...n,requestData:e.value,responseData:t.value},bodyTruncated:true}}function bodyBytes(n){let e=0;if(n.requestData!=null){e+=Math.min(n.requestSize??0,BODY_LIMIT)}if(n.responseData!=null){e+=Math.min(n.responseSize??0,BODY_LIMIT)}return e}function applyBodyBudget(n){let e=0;for(const r of n)e+=bodyBytes(r.event);if(e<=TOTAL_BODY_BUDGET)return n;const t=[...n].sort((r,i)=>{if(r.pinned!==i.pinned)return r.pinned?-1:1;return i.savedAt-r.savedAt});const s=new Set;let o=0;for(const r of t){const i=bodyBytes(r.event);if(o+i<=TOTAL_BODY_BUDGET){o+=i}else{s.add(r.key)}}if(s.size===0)return n;return n.map(r=>s.has(r.key)?{...r,event:{...r.event,requestData:void 0,responseData:void 0},bodyTruncated:true}:r)}function parseRecords(n){if(!Array.isArray(n))return[];const e=[];for(const t of n){if(!t||typeof t!=="object")continue;const s=t;if(typeof s.key!=="string")continue;if(!isStorableEvent(s.event))continue;if(!s.pinned&&!s.saved)continue;e.push({key:s.key,event:{...s.event,id:`saved:${s.key}`},pinned:!!s.pinned,saved:!!s.saved,savedAt:typeof s.savedAt==="number"?s.savedAt:0,sessionId:typeof s.sessionId==="string"?s.sessionId:"unknown",liveId:typeof s.liveId==="string"?s.liveId:"",bodyTruncated:!!s.bodyTruncated})}return e}class NetworkSavedStore{records=[];listeners=new Set;loaded=false;loadPromise=null;dirty=false;keyCounter=0;trackedLiveIds=new Set;state=EMPTY_STATE;remote=null;remoteEchoUntil=0;getState(){return this.state}enableRemoteMode(e){this.remote=e}disableRemoteMode(){this.remote=null}replaceRecords(e,t=false){if(!this.remote)return;if(!t&&Date.now()<this.remoteEchoUntil)return;this.records=e.filter(s=>isStorableEvent(s.event));this.rebuild();this.emit()}sessionMatches(e){return this.remote!==null||e.sessionId===SESSION_ID}getRecords(){return this.records}subscribe(e){this.listeners.add(e);void this.ensureLoaded();return()=>{this.listeners.delete(e)}}getEventById(e){for(const t of this.records){if(t.event.id===e)return t.event}return null}isPinned(e){return this.state.pinnedLiveIds.has(e)}isSaved(e){return this.state.savedLiveIds.has(e)}syncFromLive(e){if(this.trackedLiveIds.size===0)return;if(!this.trackedLiveIds.has(e.id))return;const t=this.records.findIndex(o=>this.sessionMatches(o)&&o.liveId===e.id);if(t===-1)return;const s=snapshot(e);this.commit(this.records.map((o,r)=>r===t?{...o,event:s.event,bodyTruncated:s.bodyTruncated}:o))}togglePin(e){return this.setFlag(e,"pinned")}toggleSave(e){return this.setFlag(e,"saved")}remove(e){if(!this.records.some(t=>t.key===e))return;this.remote?.removeRecord(e);this.commit(this.records.filter(t=>t.key!==e))}clearSaved(){if(!this.records.some(e=>e.saved))return;this.remote?.clearSaved();this.commit(this.records.filter(e=>e.pinned).map(e=>({...e,saved:false})))}clearPinned(){if(!this.records.some(e=>e.pinned))return;this.remote?.clearPinned();this.commit(this.records.filter(e=>e.saved).map(e=>({...e,pinned:false})))}setFlag(e,t){if(!isStorableEvent(e))return{ok:false,reason:"invalid-event"};const s=this.findRecordFor(e);if(this.remote){const d=s?!s[t]:true;if(t==="pinned")this.remote.setPinned(e.id,d);else this.remote.setSaved(e.id,d);this.remoteEchoUntil=Date.now()+REMOTE_ECHO_GRACE_MS}if(s){const d=!s[t];if(d&&!this.hasRoomFor(t,s.key)){return{ok:false,reason:t==="pinned"?"pin-cap":"saved-cap"}}const c={...s,[t]:d};this.commit(c.pinned||c.saved?this.records.map(a=>a.key===s.key?c:a):this.records.filter(a=>a.key!==s.key));return{ok:true,active:d}}if(!this.hasRoomFor(t,null)){return{ok:false,reason:t==="pinned"?"pin-cap":"saved-cap"}}const o=Date.now();const r=snapshot(e);const i={key:`${SESSION_ID}_${++this.keyCounter}`,event:r.event,pinned:t==="pinned",saved:t==="saved",savedAt:o,sessionId:SESSION_ID,liveId:e.id,bodyTruncated:r.bodyTruncated};this.commit(this.evictIfNeeded([i,...this.records]));return{ok:true,active:true}}findRecordFor(e){return this.records.find(t=>t.event.id===e.id||this.sessionMatches(t)&&t.liveId===e.id)}hasRoomFor(e,t){const s=e==="pinned"?MAX_PINNED:MAX_SAVED;const o=this.records.filter(r=>r[e]&&r.key!==t).length;return o<s}evictIfNeeded(e){const t=e.filter(r=>r.saved);if(t.length<=MAX_SAVED)return e;const s=t.filter(r=>!r.pinned).sort((r,i)=>r.savedAt-i.savedAt).slice(0,t.length-MAX_SAVED);if(s.length===0)return e;const o=new Set(s.map(r=>r.key));return e.filter(r=>!o.has(r.key))}ensureLoaded(){if(this.remote)return Promise.resolve();if(this.loaded)return Promise.resolve();if(this.loadPromise)return this.loadPromise;this.loadPromise=(async()=>{try{const e=await _sharedUi.persistentStorage.getItem(_sharedUi.devToolsStorageKeys.network.saved());if(e&&!this.dirty){this.records=parseRecords(JSON.parse(e));this.rebuild()}}catch{}finally{this.loaded=true;this.emit()}})();return this.loadPromise}persist(){if(this.remote)return;_sharedUi.persistentStorage.setItem(_sharedUi.devToolsStorageKeys.network.saved(),JSON.stringify(this.records)).catch(()=>{})}commit(e){this.dirty=true;this.records=applyBodyBudget(e);this.rebuild();this.emit();this.persist()}rebuild(){const e=[];const t=[];const s=new Set;const o=new Set;const r=new Set;for(const i of this.records){if(i.pinned)e.push(i);if(i.saved)t.push(i);if(!this.sessionMatches(i)||!i.liveId)continue;r.add(i.liveId);if(i.pinned)s.add(i.liveId);if(i.saved)o.add(i.liveId)}this.trackedLiveIds=r;this.state={records:this.records,pinnedEvents:e.map(i=>i.event),savedRecords:t,pinnedLiveIds:s,savedLiveIds:o}}emit(){this.listeners.forEach(e=>e())}}const networkSavedStore=exports.networkSavedStore=new NetworkSavedStore;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{getAccountAccess as
|
|
1
|
+
"use strict";import{isBuoyRequest as f,getAccountAccess as d}from"@buoy-gg/shared-ui";import{BaseEventStore as m}from"@buoy-gg/shared-ui";import{extractOperationName as l}from"./extractOperationName";import{networkListener as h,addNetworkListener as p,getNetworkListenerCount as b,stopNetworkListener as g}from"./networkListener";import{networkSavedStore as v}from"./networkSavedStore";const y=200;class w extends m{replaceEvents(e){super.replaceEvents(e.filter(t=>!f(t.url)))}pendingRequests=new Map;rawListenerUnsubscribe=null;bootBuffer=[];bootBufferUnsubscribe=null;mirrorMode=false;constructor(){super({storeName:"network",maxEvents:500})}startBootCapture(){if(d().status==="locked")return;if(this.mirrorMode||this.bootBufferUnsubscribe||this.isCapturing()){return}const e=h();if(!e.isActive){e.startListening()}this.bootBufferUnsubscribe=p(t=>{this.bootBuffer.push(t);if(this.bootBuffer.length>y)this.bootBuffer.shift()})}takeBootBuffer(){if(this.bootBufferUnsubscribe){this.bootBufferUnsubscribe();this.bootBufferUnsubscribe=null}const e=this.bootBuffer;this.bootBuffer=[];return e}startCapturing(){const e=h();if(!e.isActive){e.startListening()}for(const t of this.takeBootBuffer()){this.processNetworkEvent(t)}if(!this.rawListenerUnsubscribe){this.rawListenerUnsubscribe=p(t=>{this.processNetworkEvent(t)})}e.adoptEarlyRequests()}stopCapturing(){this.takeBootBuffer();if(this.rawListenerUnsubscribe){this.rawListenerUnsubscribe();this.rawListenerUnsubscribe=null}if(b()===0){g()}}disableCapture(){this.mirrorMode=true;this.takeBootBuffer();if(b()===0){g()}super.disableCapture()}isCapturing(){return this.rawListenerUnsubscribe!==null}ensureInterception(){if(!this.isCapturing())return;h().startListening()}subscribeToEvents(e){const t=super.subscribeToEvents(e);this.ensureInterception();return t}processNetworkEvent(e){if(d().status==="locked")return;const{request:t}=e;if(f(t.url))return;if(e.type==="request"){if(this.events.some(u=>u.id===t.id))return;const r=t.params?`?${new URLSearchParams(t.params).toString()}`:"";const s=`${t.url}${r}`;let n;let o;if(t.client==="graphql"){const u=l(t.data);n=u||void 0;if(t.data&&typeof t.data==="object"&&"variables"in t.data&&t.data.variables&&typeof t.data.variables==="object"){o=t.data.variables}}const a={id:t.id,method:t.method,url:s,host:this.extractHost(t.url),path:this.extractPath(t.url),query:r,timestamp:e.timestamp.getTime(),requestHeaders:t.headers||{},requestData:t.data,requestSize:this.getDataSize(t.data),responseHeaders:{},requestClient:t.client,operationName:n,graphqlVariables:o,override:e.override,condition:e.condition};this.pendingRequests.set(t.id,a);this.events=[a,...this.events].slice(0,this.maxEvents);this.notify(a);this.notifyArrayListeners()}else if(e.type==="request-body"){const r=this.events.find(n=>n.id===t.id);if(!r)return;const s={...r,requestData:t.data,requestSize:this.getDataSize(t.data)};if(t.client==="graphql"){s.operationName=l(t.data)||void 0;const n=t.data?.variables;if(n&&typeof n==="object")s.graphqlVariables=n}this.events=this.events.map(n=>n.id===t.id?s:n);if(this.pendingRequests.has(t.id))this.pendingRequests.set(t.id,s);v.syncFromLive(s);this.notify(s);this.notifyArrayListeners()}else if(e.type==="response"||e.type==="error"){const r=this.events.findIndex(s=>s.id===t.id);if(r!==-1){const s={...this.events[r],duration:e.duration,timings:e.timings};if(e.response){s.status=e.response.status;s.statusText=e.response.statusText;s.responseHeaders=e.response.headers||{};s.responseData=e.response.body;s.responseSize=e.response.size||0;s.responseType=e.response.headers?.["content-type"]}if(e.error){s.error=e.error.message;s.status=s.status||0}if(e.override)s.override=e.override;this.events=this.events.map((n,o)=>o===r?s:n);this.pendingRequests.delete(t.id);v.syncFromLive(s);this.notify(s);this.notifyArrayListeners()}}}extractHost(e){try{const t=new URL(e);return t.hostname}catch{return""}}extractPath(e){try{const t=new URL(e);return t.pathname}catch{return e}}getDataSize(e){if(!e)return 0;if(typeof e==="string")return e.length;try{return JSON.stringify(e).length}catch{return 0}}getEventById(e){return this.events.find(t=>t.id===e)}clearEvents(){super.clearEvents();this.pendingRequests.clear()}onEvent(e,t=true){const r=this.subscribe(e);if(t&&this.events.length>0){const s=[...this.events].reverse();for(const n of s){try{e(n)}catch{}}}return r}getStats(){const e=this.events.length;const t=this.events.filter(i=>i.status&&i.status>=200&&i.status<300).length;const r=this.events.filter(i=>i.error||i.status&&i.status>=400).length;const s=this.events.filter(i=>!i.status&&!i.error).length;const n=this.events.filter(i=>i.duration).map(i=>i.duration);const o=n.length>0?n.reduce((i,c)=>i+c,0)/n.length:0;const a=this.events.reduce((i,c)=>i+(c.requestSize||0),0);const u=this.events.reduce((i,c)=>i+(c.responseSize||0),0);return{totalRequests:e,successfulRequests:t,failedRequests:r,pendingRequests:s,totalDataSent:a,totalDataReceived:u,averageDuration:Math.round(o)}}filterEvents(e){let t=[...this.events];if(e.method){t=t.filter(r=>r.method===e.method)}if(e.status){switch(e.status){case"success":t=t.filter(r=>r.status&&r.status>=200&&r.status<300);break;case"error":t=t.filter(r=>r.error||r.status&&r.status>=400);break;case"pending":t=t.filter(r=>!r.status&&!r.error);break}}if(e.searchText){const r=e.searchText.toLowerCase();t=t.filter(s=>s.url.toLowerCase().includes(r)||s.method.toLowerCase().includes(r)||s.error&&s.error.toLowerCase().includes(r))}if(e.host){t=t.filter(r=>r.host===e.host)}return t}}export const networkEventStore=new w;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
"use strict";import{resolveRequestUrl as
|
|
1
|
+
"use strict";import{isBuoyRequest as K}from"@buoy-gg/shared-ui";import{resolveRequestUrl as B}from"./resolveRequestUrl";import{nextRequestId as D}from"./requestId";import{runConditionXhr as V}from"../conditions/xhr";import{snapshotNetworkCondition as G}from"../conditions/store";import{throwIfAborted as j,waitBeforeDispatch as Q}from"../conditions/wait";import{overrideForRequest as J}from"../overrides/engine";import{runOverride as Z,hasPendingStandardRequest as ee}from"../overrides/applyToXhr";import{canSynthesizeResponse as te,synthesizeFetchError as se,synthesizeResponse as ne}from"../overrides/applyToFetch";import{markForOutcome as $}from"../overrides/types";import{httpStatusText as re,xhrCompletionKind as oe}from"./httpCompletion";import{realNow as _}from"./realNow";let O;function P(g){const e=globalThis.__buoyHeaderInjectors;if(!e||e.length===0)return void 0;let t;for(const s of e){try{const c=s(g);if(c)t={...t,...c}}catch{}}return t}function ie(){if(O!==void 0)return O;O=null;try{if(typeof __DEV__!=="undefined"&&!__DEV__)return O;const g=require("react-native");const e=g?.NativeModules?.SourceCode;const t=e?.getConstants?.().scriptURL??e?.scriptURL;if(typeof t==="string"&&/^https?:\/\//.test(t)){const s=new URL(t);O=`${s.protocol}//${s.host}`}}catch{O=null}return O}let N=false;function ae(g){const e={};if(!g)return e;if(typeof Headers!=="undefined"&&g instanceof Headers)g.forEach((t,s)=>{e[s]=t});else if(Array.isArray(g))for(const[t,s]of g)e[t]=s;else Object.assign(e,g);return e}export const BUOY_FETCH_INTERCEPTOR_FLAG="__buoyNetworkFetchIntercepted";export const BUOY_XHR_INTERCEPTOR_FLAG="__buoyNetworkXhrIntercepted";const ce=["text/event-stream","application/x-ndjson","application/stream+json"];const Y="[streaming\u2026]";let A=false;function de(){if(A)return true;const g=globalThis.document;A=!!g?.querySelector?.("[ng-version]");return A}function W(g){if(!g)return false;const e=g.toLowerCase();return ce.some(t=>e.includes(t))}const ue="__BUOY_INTERNAL_HOSTS__";function he(g){const e=globalThis[ue];if(!(e instanceof Set)||e.size===0)return false;let t;try{t=new URL(g).host.toLowerCase()}catch{return false}for(const s of e){if(typeof s==="string"&&s&&t===s.toLowerCase())return true}return false}class le{listeners=[];isListening=false;patchedFetch=null;patchedXHROpen=null;patchedXHRSend=null;patchedXHRSetRequestHeader=null;fetchGeneration=0;xhrGeneration=0;constructor(){this.originalFetch=globalThis.fetch;this.originalXHROpen=XMLHttpRequest.prototype.open;this.originalXHRSend=XMLHttpRequest.prototype.send;this.originalXHRSetRequestHeader=XMLHttpRequest.prototype.setRequestHeader}shouldIgnoreUrl(e){if(K(e))return true;try{const t=new URL(e);if(t.hostname==="keygen.sh"||t.hostname.endsWith(".keygen.sh"))return true;if((t.hostname==="buoy.gg"||t.hostname==="www.buoy.gg")&&(t.pathname.startsWith("/api/license")||t.pathname.startsWith("/api/settings/")))return true;const s=t.hostname==="localhost"||t.hostname==="127.0.0.1"||t.hostname==="10.0.2.2";if(s&&["8081","8802"].includes(t.port))return true;const c=ie();if(c&&`${t.protocol}//${t.host}`===c)return true}catch{return false}return he(e)}emit(e){this.listeners.forEach(t=>{try{t(e)}catch(s){}})}parseUrl(e){let t=null;const s=e.indexOf("?");if(s>-1){t={};e.substring(s+1).split("&").forEach(c=>{const[a,r]=c.split("=");if(a&&r!==void 0){t[a]=decodeURIComponent(r.replace(/\+/g," "))}})}return{url:s>-1?e.substring(0,s):e,params:t}}async readStreamedBody(e,t=256*1024){const s=e.body;if(!s||typeof s.getReader!=="function"){const f=await e.text();return f.length>t?{body:`${f.slice(0,t)}
|
|
2
2
|
|
|
3
|
-
... [truncated]`,size:f.length}:{body:f,size:f.length}}const c=s.getReader();const a=new TextDecoder;let r="";let
|
|
3
|
+
... [truncated]`,size:f.length}:{body:f,size:f.length}}const c=s.getReader();const a=new TextDecoder;let r="";let h=0;let R=false;try{for(;;){const{done:f,value:i}=await c.read();if(f)break;h+=i?.byteLength??0;if(!R){r+=a.decode(i,{stream:true});if(h>=t){r=`${r.slice(0,t)}
|
|
4
4
|
|
|
5
|
-
... [truncated]`;
|
|
5
|
+
... [truncated]`;R=true;break}}}if(!R)r+=a.decode()}finally{try{void Promise.resolve(c.cancel()).catch(()=>{})}catch{}try{c.releaseLock()}catch{}}return{body:r,size:h}}async processResponseBody(e,t=1024*1024){try{const s=e.headers.get("content-length");if(s){const r=parseInt(s,10);if(!isNaN(r)&&r>t){return{body:`[Response too large: ${this.formatBytes(r)}]`,size:r,truncated:true}}}const c=await e.text();const a=c.length;if(a>t){const r=c.substring(0,t);const h=a-t;return{body:`${r}
|
|
6
6
|
|
|
7
|
-
... [truncated, ${this.formatBytes(u)} omitted]`,size:a,truncated:true}}try{return{body:JSON.parse(c),size:a,truncated:false}}catch{return{body:c,size:a,truncated:false}}}catch(s){return{body:"~~~ unable to read body ~~~",size:0,truncated:false}}}formatBytes(e){if(e===0)return"0 B";const t=1024;const s=["B","KB","MB","GB"];const c=Math.floor(Math.log(e)/Math.log(t));return`${Math.round(e/Math.pow(t,c)*100)/100} ${s[c]}`}handleXHRResponse(e,t,s,c,a,r,u,g,f=false,i="xhr",d,L){const m=g?_()-g:0;const l=e._buoyTtfb;const q=l===void 0?void 0:{ttfb:l,download:Math.max(0,m-l)};if(f||e.status===0){this.emit({type:"error",timestamp:new Date,duration:m,request:{id:t||"unknown",url:s,method:c,headers:a,data:r,params:u||void 0,client:i},error:{message:f?"Request failed":"Network error or request aborted"},override:d,condition:L});return}let n;let p=0;try{const o=e.response;if(e.responseType==="json"&&o){n=o;p=JSON.stringify(o).length}else if(e.responseType===""||e.responseType==="text"){if(e.responseText){p=e.responseText.length;try{n=JSON.parse(e.responseText)}catch{n=e.responseText}}}else if(e.responseType==="arraybuffer"){if(o){try{const y=new TextDecoder("utf-8").decode(o);p=y.length;try{n=JSON.parse(y)}catch{n=y}}catch(y){n=`[arraybuffer response - ${o.byteLength||0} bytes]`;p=o.byteLength||0}}else{n=`[arraybuffer response - no data]`;p=0}}else if(e.responseType==="blob"){if(o instanceof Blob){n=`[blob response - ${o.size} bytes, type: ${o.type||"unknown"}]`;p=o.size}else if(o){try{n=typeof o==="string"?JSON.parse(o):o;p=JSON.stringify(n).length}catch{n=`[blob response - unable to parse]`;p=0}}else{n=`[blob response - no data]`;p=0}}else if(o){if(typeof o==="string"){n=o;p=o.length;try{n=JSON.parse(o)}catch{}}else if(typeof o==="object"){n=o;p=JSON.stringify(o).length}else{n=String(o);p=String(o).length}}}catch(o){n="~~~ unable to read body ~~~"}const R={};try{const o=e.getAllResponseHeaders();if(o){o.split("\r\n").forEach(y=>{if(y){const w=y.indexOf(": ");if(w>0){const h=y.substring(0,w).toLowerCase();const H=y.substring(w+2);R[h]=H}}})}}catch{}if(se(e.status)==="response"){this.emit({type:"response",timestamp:new Date,duration:m,timings:q,request:{id:t||"unknown",url:s,method:c,headers:a,data:r,params:u||void 0,client:i},response:{status:e.status,statusText:te(e.status,e.statusText),headers:R,body:n,size:p},override:d,condition:L})}else{this.emit({type:"error",timestamp:new Date,duration:m,request:{id:t||"unknown",url:s,method:c,headers:a,data:r,params:u||void 0,client:i},response:{status:e.status,statusText:e.statusText,headers:R,body:n,size:p},error:{message:"Network Error"},override:d,condition:L})}}isFetchInterceptionLive(){return globalThis.fetch[BUOY_FETCH_INTERCEPTOR_FLAG]===true}isXhrInterceptionLive(){return XMLHttpRequest.prototype.send[BUOY_XHR_INTERCEPTOR_FLAG]===true}isInterceptionLive(){return this.isFetchInterceptionLive()&&this.isXhrInterceptionLive()}startListening(){const e=this.isListening&&this.isFetchInterceptionLive();const t=this.isListening&&this.isXhrInterceptionLive();if(e&&t){return}if(!e){this.installFetchInterceptor()}if(!t){this.installXhrInterceptor()}this.isListening=true;if(__DEV__){}}installFetchInterceptor(){const e=this;const t=globalThis.fetch.bind(globalThis);this.originalFetch=globalThis.fetch;const s=++this.fetchGeneration;const c=async(a,r)=>{const u=U(typeof a==="string"?a:a instanceof URL?a.href:a.url);if(s!==e.fetchGeneration){return t(a,r)}if(e.shouldIgnoreUrl(u)){return t(a,r)}const g=_();const f=B("fetch");const i=typeof a==="object"&&"method"in a?a:void 0;const d=r?.method??i?.method??"GET";const L=r?.signal!==void 0?r.signal:i?.signal;G(L);const m=z(u);const{url:l,params:q}=e.parseUrl(u);let n={};const p=r?.headers??i?.headers;if(p){if(p instanceof Headers){p.forEach((h,H)=>{n[H]=h})}else if(Array.isArray(p)){p.forEach(([h,H])=>{n[h]=H})}else{n={...p}}}Object.assign(n,$(u));let R;if(r?.body){if(typeof r.body==="string"){try{R=JSON.parse(r.body)}catch{R=r.body}}else{R=r.body}}const o=n["X-Request-Client"]||n["x-request-client"]||"fetch";const y=m?.profile!=="offline"&&Q()?j(u,d,n):null;const w=y?J(y):void 0;e.emit({type:"request",timestamp:new Date,request:{id:f||"unknown",url:l,method:d,headers:n,data:R,params:q||void 0,client:o},override:w,condition:m});if(r?.body===void 0&&i?.body&&!i.bodyUsed){try{const h=i.clone();void e.readStreamedBody(h).then(({body:H})=>{try{R=JSON.parse(H)}catch{R=H}e.emit({type:"request-body",timestamp:new Date,request:{id:f||"unknown",url:l,method:d,data:R,client:o}})}).catch(()=>{})}catch{}}try{if(m||y)await K((m?.delayMs??0)+(y?.delayMs??0),L);G(L);if(m?.profile==="offline")throw new TypeError("Network request failed (Buoy Offline)");if(y?.kind==="fail")throw Z(y);let h;if(y?.kind==="respond"){h=ee(u,y)}else{const T=D;D=true;let X;try{X=t(a,r)}finally{D=T}h=await X}const H=_()-g;const S=typeof h.body?.getReader==="function"||ie(h.headers?.get?.("content-type"));const E=h.clone();const{body:F,size:I}=S?{body:P,size:0}:await e.processResponseBody(E);const x=_()-g;const C=Math.max(0,x-H);const M=C>0?{ttfb:H,download:C}:void 0;const N={};h.headers.forEach((T,X)=>{N[X.toLowerCase()]=T});e.emit({type:"response",timestamp:new Date,duration:x,timings:M,request:{id:f||"unknown",url:l,method:d,headers:n,data:R,params:q||void 0,client:o},response:{status:h.status,statusText:h.statusText,headers:N,body:F,size:I},override:w,condition:m});if(S){void e.readStreamedBody(E).then(T=>{let X=T.body;if(h.headers?.get?.("content-type")?.includes("json")){try{X=JSON.parse(T.body)}catch{}}e.emit({type:"response",timestamp:new Date,duration:_()-g,timings:M,request:{id:f||"unknown",url:l,method:d,headers:n,data:R,params:q||void 0,client:o},response:{status:h.status,statusText:h.statusText,headers:N,body:X,size:T.size},override:w,condition:m})}).catch(()=>{})}return h}catch(h){const H=_()-g;e.emit({type:"error",timestamp:new Date,duration:H,request:{id:f||"unknown",url:l,method:d,headers:n,data:R,params:q||void 0,client:o},error:{message:h instanceof Error?h.message:"Network error",stack:h instanceof Error?h.stack:void 0},override:w,condition:m});throw h}};c[BUOY_FETCH_INTERCEPTOR_FLAG]=true;this.patchedFetch=c;globalThis.fetch=this.patchedFetch}installXhrInterceptor(){const e=this;const t=XMLHttpRequest.prototype.open;const s=XMLHttpRequest.prototype.send;const c=XMLHttpRequest.prototype.setRequestHeader;this.originalXHROpen=t;this.originalXHRSend=s;this.originalXHRSetRequestHeader=c;const a=++this.xhrGeneration;const r=new WeakMap;const u=function(i,d,L,m,l){const q=t.call(this,i,d,L??true,m,l);if(a===e.xhrGeneration){r.get(this)?.();const n=this;n._buoyRequestId=B("xhr");n._method=i;n._url=U(d);n._buoyStartTime=_();n._requestHeaders={}}return q};const g=function(i,d){const L=this;if(a===e.xhrGeneration&&L._requestHeaders){L._requestHeaders[i]=d}return c.call(this,i,d)};const f=function(i){if(a!==e.xhrGeneration||D){return s.call(this,i)}if(W(this))throw new DOMException("The request has already been sent.","InvalidStateError");if(this.readyState!==1||this._sent){return s.call(this,i)}const d=this;const L=d._buoyRequestId;const m=d._method||"GET";const l=d._url||"";const q=_();d._buoyStartTime=q;d._buoyTtfb=void 0;const n=d._requestHeaders||{};Object.assign(n,$(l));if(e.shouldIgnoreUrl(l)){return s.call(this,i)}const{url:p,params:R}=e.parseUrl(l);let o;if(i){if(typeof i==="string"){try{o=JSON.parse(i)}catch{o=i}}else{o=i}}const y=n["X-Request-Client"]||n["x-request-client"];const w=n["Accept"]||n["accept"]||"";const h=w.includes("application/json")&&w.includes("text/plain")&&w.includes("*/*");const H=y||(h?"axios":"xhr");const S=z(l);const E=S?.profile==="offline"?null:j(l,m,n);const F=E?J(E):void 0;e.emit({type:"request",timestamp:new Date,request:{id:L||"unknown",url:p,method:m,headers:n,data:o,params:R||void 0,client:H},override:F,condition:S});let I=false;const x=(v=false)=>{if(I)return;I=true;e.handleXHRResponse(this,L||"unknown",p,m,n,o,R,q||0,v,H,F,S);C()};const C=()=>{r.delete(this);this.removeEventListener("load",M);this.removeEventListener("error",N);this.removeEventListener("abort",T);this.removeEventListener("readystatechange",X)};r.set(this,C);const M=()=>{x(false)};const N=()=>{x(true)};const T=()=>{x(true)};const X=()=>{if(this.readyState===2){const v=this;if(v._buoyTtfb===void 0&&v._buoyStartTime){v._buoyTtfb=_()-v._buoyStartTime}}if(this.readyState===4&&!I){x(false)}};this.addEventListener("load",M);this.addEventListener("error",N);this.addEventListener("abort",T);this.addEventListener("readystatechange",X);if(S){Y(this,l,S,E,()=>s.call(this,i));return}if(E){const v=V(this,l,E,()=>s.call(this,i));if(v)return}return s.call(this,i)};f[BUOY_XHR_INTERCEPTOR_FLAG]=true;this.patchedXHROpen=u;this.patchedXHRSend=f;this.patchedXHRSetRequestHeader=g;XMLHttpRequest.prototype.open=this.patchedXHROpen;XMLHttpRequest.prototype.send=this.patchedXHRSend;XMLHttpRequest.prototype.setRequestHeader=this.patchedXHRSetRequestHeader}stopListening(){if(!this.isListening){return}this.fetchGeneration++;this.xhrGeneration++;if(this.patchedFetch&&globalThis.fetch===this.patchedFetch){globalThis.fetch=this.originalFetch}if(this.patchedXHROpen&&XMLHttpRequest.prototype.open===this.patchedXHROpen){XMLHttpRequest.prototype.open=this.originalXHROpen}if(this.patchedXHRSend&&XMLHttpRequest.prototype.send===this.patchedXHRSend){XMLHttpRequest.prototype.send=this.originalXHRSend}if(this.patchedXHRSetRequestHeader&&XMLHttpRequest.prototype.setRequestHeader===this.patchedXHRSetRequestHeader){XMLHttpRequest.prototype.setRequestHeader=this.originalXHRSetRequestHeader}this.patchedFetch=null;this.patchedXHROpen=null;this.patchedXHRSend=null;this.patchedXHRSetRequestHeader=null;this.isListening=false;if(__DEV__){}}adoptEarlyRequests(){const e=globalThis.__BUOY_EARLY_NETWORK__;if(e?.version!==1)return;for(const t of e.adopt()){try{if(t.kind==="fetch")this.adoptEarlyFetch(t);else this.adoptEarlyXhr(t)}catch{}}}adoptEarlyFetch(e){const{input:t,init:s}=e;const c=typeof t==="object"&&"method"in t?t:void 0;const a=U(typeof t==="string"?t:t instanceof URL?t.href:t.url);if(this.shouldIgnoreUrl(a))return;const r=B("fetch");const u=s?.method??c?.method??"GET";const{url:g,params:f}=this.parseUrl(a);const i=re(s?.headers??c?.headers);let d=s?.body;if(typeof d==="string"){try{d=JSON.parse(d)}catch{}}const L=i["X-Request-Client"]||i["x-request-client"]||"fetch";const m=()=>({id:r,url:g,method:u,headers:i,data:d,params:f||void 0,client:L});this.emit({type:"request",timestamp:new Date(e.start),request:m()});if(e.requestCopy){void this.readStreamedBody(e.requestCopy).then(({body:l})=>{try{d=JSON.parse(l)}catch{d=l}this.emit({type:"request-body",timestamp:new Date,request:{id:r,url:g,method:u,data:d,client:L}})}).catch(()=>{})}void e.settled.then(async({response:l,clone:q,error:n,headersAt:p})=>{if(!l){this.emit({type:"error",timestamp:new Date,duration:p-e.start,request:m(),error:{message:n instanceof Error?n.message:"Network error",stack:n instanceof Error?n.stack:void 0}});return}const{body:R,size:o}=q?await this.processResponseBody(q):{body:P,size:0};const y=Math.max(0,_()-e.start);const w=p-e.start;const h={};l.headers.forEach((H,S)=>{h[S.toLowerCase()]=H});this.emit({type:"response",timestamp:new Date,duration:y,timings:y>w?{ttfb:w,download:y-w}:void 0,request:m(),response:{status:l.status,statusText:l.statusText,headers:h,body:R,size:o}})})}adoptEarlyXhr(e){const t=U(e.url);if(this.shouldIgnoreUrl(t))return;const s=B("xhr");const c=e.method.toUpperCase();const{url:a,params:r}=this.parseUrl(t);let u=e.body;if(typeof u==="string"){try{u=JSON.parse(u)}catch{}}const g=e.headers["X-Request-Client"]||e.headers["x-request-client"]||"xhr";this.emit({type:"request",timestamp:new Date(e.start),request:{id:s,url:a,method:c,headers:e.headers,data:u,params:r||void 0,client:g}});const f=e.xhr;const i=()=>{const d=(f._buoyEarlyEnd??_())-e.start;this.handleXHRResponse(f,s,a,c,e.headers,u,r,_()-d,false,g)};if(f.readyState===4)i();else f.addEventListener("loadend",i,{once:true})}addListener(e){this.listeners.push(e);return()=>{const t=this.listeners.indexOf(e);if(t>-1){this.listeners.splice(t,1)}}}removeAllListeners(){this.listeners=[]}get isActive(){return this.isListening}get listenerCount(){return this.listeners.length}}let k=null;const A=()=>{if(!k){k=new de}return k};export const networkListener=A;export const startNetworkListener=()=>A().startListening();export const stopNetworkListener=()=>k?.stopListening();export const addNetworkListener=b=>A().addListener(b);export const removeAllNetworkListeners=()=>k?.removeAllListeners();export const isNetworkListening=()=>k?.isActive??false;export const getNetworkListenerCount=()=>k?.listenerCount??0;export const isNetworkInterceptionLive=()=>k?.isInterceptionLive()??false;
|
|
7
|
+
... [truncated, ${this.formatBytes(h)} omitted]`,size:a,truncated:true}}try{return{body:JSON.parse(c),size:a,truncated:false}}catch{return{body:c,size:a,truncated:false}}}catch(s){return{body:"~~~ unable to read body ~~~",size:0,truncated:false}}}formatBytes(e){if(e===0)return"0 B";const t=1024;const s=["B","KB","MB","GB"];const c=Math.floor(Math.log(e)/Math.log(t));return`${Math.round(e/Math.pow(t,c)*100)/100} ${s[c]}`}handleXHRResponse(e,t,s,c,a,r,h,R,f=false,i="xhr",d,L){const m=R?_()-R:0;const l=e._buoyTtfb;const w=l===void 0?void 0:{ttfb:l,download:Math.max(0,m-l)};if(f||e.status===0){this.emit({type:"error",timestamp:new Date,duration:m,request:{id:t||"unknown",url:s,method:c,headers:a,data:r,params:h||void 0,client:i},error:{message:f?"Request failed":"Network error or request aborted"},override:d,condition:L});return}let n;let p=0;try{const o=e.response;if(e.responseType==="json"&&o){n=o;p=JSON.stringify(o).length}else if(e.responseType===""||e.responseType==="text"){if(e.responseText){p=e.responseText.length;try{n=JSON.parse(e.responseText)}catch{n=e.responseText}}}else if(e.responseType==="arraybuffer"){if(o){try{const y=new TextDecoder("utf-8").decode(o);p=y.length;try{n=JSON.parse(y)}catch{n=y}}catch(y){n=`[arraybuffer response - ${o.byteLength||0} bytes]`;p=o.byteLength||0}}else{n=`[arraybuffer response - no data]`;p=0}}else if(e.responseType==="blob"){if(o instanceof Blob){n=`[blob response - ${o.size} bytes, type: ${o.type||"unknown"}]`;p=o.size}else if(o){try{n=typeof o==="string"?JSON.parse(o):o;p=JSON.stringify(n).length}catch{n=`[blob response - unable to parse]`;p=0}}else{n=`[blob response - no data]`;p=0}}else if(o){if(typeof o==="string"){n=o;p=o.length;try{n=JSON.parse(o)}catch{}}else if(typeof o==="object"){n=o;p=JSON.stringify(o).length}else{n=String(o);p=String(o).length}}}catch(o){n="~~~ unable to read body ~~~"}const b={};try{const o=e.getAllResponseHeaders();if(o){o.split("\r\n").forEach(y=>{if(y){const q=y.indexOf(": ");if(q>0){const u=y.substring(0,q).toLowerCase();const H=y.substring(q+2);b[u]=H}}})}}catch{}if(oe(e.status)==="response"){this.emit({type:"response",timestamp:new Date,duration:m,timings:w,request:{id:t||"unknown",url:s,method:c,headers:a,data:r,params:h||void 0,client:i},response:{status:e.status,statusText:re(e.status,e.statusText),headers:b,body:n,size:p},override:d,condition:L})}else{this.emit({type:"error",timestamp:new Date,duration:m,request:{id:t||"unknown",url:s,method:c,headers:a,data:r,params:h||void 0,client:i},response:{status:e.status,statusText:e.statusText,headers:b,body:n,size:p},error:{message:"Network Error"},override:d,condition:L})}}isFetchInterceptionLive(){return globalThis.fetch[BUOY_FETCH_INTERCEPTOR_FLAG]===true}isXhrInterceptionLive(){return XMLHttpRequest.prototype.send[BUOY_XHR_INTERCEPTOR_FLAG]===true}isInterceptionLive(){return this.isFetchInterceptionLive()&&this.isXhrInterceptionLive()}startListening(){const e=this.isListening&&this.isFetchInterceptionLive();const t=this.isListening&&this.isXhrInterceptionLive();if(e&&t){return}if(!e){this.installFetchInterceptor()}if(!t){this.installXhrInterceptor()}this.isListening=true;if(__DEV__){}}installFetchInterceptor(){const e=this;const t=globalThis.fetch.bind(globalThis);this.originalFetch=globalThis.fetch;const s=++this.fetchGeneration;const c=async(a,r)=>{const h=B(typeof a==="string"?a:a instanceof URL?a.href:a.url);if(s!==e.fetchGeneration){return t(a,r)}if(r?.__buoyInternal||e.shouldIgnoreUrl(h)){const u=N;N=true;try{return t(a,r)}finally{N=u}}const R=_();const f=D("fetch");const i=typeof a==="object"&&"method"in a?a:void 0;const d=r?.method??i?.method??"GET";const L=r?.signal!==void 0?r.signal:i?.signal;j(L);const m=G(h);const{url:l,params:w}=e.parseUrl(h);let n={};const p=r?.headers??i?.headers;if(p){if(p instanceof Headers){p.forEach((u,H)=>{n[H]=u})}else if(Array.isArray(p)){p.forEach(([u,H])=>{n[u]=H})}else{n={...p}}}Object.assign(n,P(h));let b;if(r?.body){if(typeof r.body==="string"){try{b=JSON.parse(r.body)}catch{b=r.body}}else{b=r.body}}const o=n["X-Request-Client"]||n["x-request-client"]||"fetch";const y=m?.profile!=="offline"&&te()?J(h,d,n):null;const q=y?$(y):void 0;e.emit({type:"request",timestamp:new Date,request:{id:f||"unknown",url:l,method:d,headers:n,data:b,params:w||void 0,client:o},override:q,condition:m});if(r?.body===void 0&&i?.body&&!i.bodyUsed){try{const u=i.clone();void e.readStreamedBody(u).then(({body:H})=>{try{b=JSON.parse(H)}catch{b=H}e.emit({type:"request-body",timestamp:new Date,request:{id:f||"unknown",url:l,method:d,data:b,client:o}})}).catch(()=>{})}catch{}}try{if(m||y)await Q((m?.delayMs??0)+(y?.delayMs??0),L);j(L);if(m?.profile==="offline")throw new TypeError("Network request failed (Buoy Offline)");if(y?.kind==="fail")throw se(y);let u;if(y?.kind==="respond"){u=ne(h,y)}else{const E=N;N=true;let S;try{S=t(a,r)}finally{N=E}u=await S}const H=_()-R;const X=typeof u.body?.getReader==="function"||W(u.headers?.get?.("content-type"));const v=u.clone();const{body:U,size:C}=X?{body:Y,size:0}:await e.processResponseBody(v);const x=_()-R;const M=Math.max(0,x-H);const F=M>0?{ttfb:H,download:M}:void 0;const I={};u.headers.forEach((E,S)=>{I[S.toLowerCase()]=E});e.emit({type:"response",timestamp:new Date,duration:x,timings:F,request:{id:f||"unknown",url:l,method:d,headers:n,data:b,params:w||void 0,client:o},response:{status:u.status,statusText:u.statusText,headers:I,body:U,size:C},override:q,condition:m});if(X){const E=u.headers?.get?.("content-type");void e.readStreamedBody(v,W(E)?void 0:1024*1024).then(S=>{let T=S.body;if(E?.includes("json")){try{T=JSON.parse(S.body)}catch{}}e.emit({type:"response",timestamp:new Date,duration:_()-R,timings:F,request:{id:f||"unknown",url:l,method:d,headers:n,data:b,params:w||void 0,client:o},response:{status:u.status,statusText:u.statusText,headers:I,body:T,size:S.size},override:q,condition:m})}).catch(()=>{})}return u}catch(u){const H=_()-R;e.emit({type:"error",timestamp:new Date,duration:H,request:{id:f||"unknown",url:l,method:d,headers:n,data:b,params:w||void 0,client:o},error:{message:u instanceof Error?u.message:"Network error",stack:u instanceof Error?u.stack:void 0},override:q,condition:m});throw u}};c[BUOY_FETCH_INTERCEPTOR_FLAG]=true;this.patchedFetch=c;globalThis.fetch=this.patchedFetch}installXhrInterceptor(){const e=this;const t=XMLHttpRequest.prototype.open;const s=XMLHttpRequest.prototype.send;const c=XMLHttpRequest.prototype.setRequestHeader;this.originalXHROpen=t;this.originalXHRSend=s;this.originalXHRSetRequestHeader=c;const a=++this.xhrGeneration;const r=new WeakMap;const h=function(i,d,L,m,l){const w=t.call(this,i,d,L??true,m,l);if(a===e.xhrGeneration){r.get(this)?.();const n=this;n._buoyRequestId=D("xhr");n._method=i;n._url=B(d);n._buoyStartTime=_();n._requestHeaders={}}return w};const R=function(i,d){const L=this;if(a===e.xhrGeneration&&L._requestHeaders){L._requestHeaders[i]=d}return c.call(this,i,d)};const f=function(i){if(a!==e.xhrGeneration||N){return s.call(this,i)}if(ee(this))throw new DOMException("The request has already been sent.","InvalidStateError");if(this.readyState!==1||this._sent){return s.call(this,i)}const d=this;const L=d._buoyRequestId;const m=d._method||"GET";const l=d._url||"";const w=_();d._buoyStartTime=w;d._buoyTtfb=void 0;const n=d._requestHeaders||{};Object.assign(n,P(l));if(e.shouldIgnoreUrl(l)){return s.call(this,i)}const{url:p,params:b}=e.parseUrl(l);let o;if(i){if(typeof i==="string"){try{o=JSON.parse(i)}catch{o=i}}else{o=i}}const y=n["X-Request-Client"]||n["x-request-client"];const q=n["Accept"]||n["accept"]||"";const u=q.includes("application/json")&&q.includes("text/plain")&&q.includes("*/*")&&!de();const H=y||(u?"axios":"xhr");const X=G(l);const v=X?.profile==="offline"?null:J(l,m,n);const U=v?$(v):void 0;e.emit({type:"request",timestamp:new Date,request:{id:L||"unknown",url:p,method:m,headers:n,data:o,params:b||void 0,client:H},override:U,condition:X});let C=false;const x=(T=false)=>{if(C)return;C=true;e.handleXHRResponse(this,L||"unknown",p,m,n,o,b,w||0,T,H,U,X);M()};const M=()=>{r.delete(this);this.removeEventListener("load",F);this.removeEventListener("error",I);this.removeEventListener("abort",E);this.removeEventListener("readystatechange",S)};r.set(this,M);const F=()=>{x(false)};const I=()=>{x(true)};const E=()=>{x(true)};const S=()=>{if(this.readyState===2){const T=this;if(T._buoyTtfb===void 0&&T._buoyStartTime){T._buoyTtfb=_()-T._buoyStartTime}}if(this.readyState===4&&!C){x(false)}};this.addEventListener("load",F);this.addEventListener("error",I);this.addEventListener("abort",E);this.addEventListener("readystatechange",S);if(X){V(this,l,X,v,()=>s.call(this,i));return}if(v){const T=Z(this,l,v,()=>s.call(this,i));if(T)return}return s.call(this,i)};f[BUOY_XHR_INTERCEPTOR_FLAG]=true;this.patchedXHROpen=h;this.patchedXHRSend=f;this.patchedXHRSetRequestHeader=R;XMLHttpRequest.prototype.open=this.patchedXHROpen;XMLHttpRequest.prototype.send=this.patchedXHRSend;XMLHttpRequest.prototype.setRequestHeader=this.patchedXHRSetRequestHeader}stopListening(){if(!this.isListening){return}this.fetchGeneration++;this.xhrGeneration++;if(this.patchedFetch&&globalThis.fetch===this.patchedFetch){globalThis.fetch=this.originalFetch}if(this.patchedXHROpen&&XMLHttpRequest.prototype.open===this.patchedXHROpen){XMLHttpRequest.prototype.open=this.originalXHROpen}if(this.patchedXHRSend&&XMLHttpRequest.prototype.send===this.patchedXHRSend){XMLHttpRequest.prototype.send=this.originalXHRSend}if(this.patchedXHRSetRequestHeader&&XMLHttpRequest.prototype.setRequestHeader===this.patchedXHRSetRequestHeader){XMLHttpRequest.prototype.setRequestHeader=this.originalXHRSetRequestHeader}this.patchedFetch=null;this.patchedXHROpen=null;this.patchedXHRSend=null;this.patchedXHRSetRequestHeader=null;this.isListening=false;if(__DEV__){}}adoptEarlyRequests(){const e=globalThis.__BUOY_EARLY_NETWORK__;if(e?.version!==1)return;for(const t of e.adopt()){try{if(t.kind==="fetch")this.adoptEarlyFetch(t);else this.adoptEarlyXhr(t)}catch{}}}adoptEarlyFetch(e){const{input:t,init:s}=e;const c=typeof t==="object"&&"method"in t?t:void 0;const a=B(typeof t==="string"?t:t instanceof URL?t.href:t.url);if(this.shouldIgnoreUrl(a))return;const r=D("fetch");const h=s?.method??c?.method??"GET";const{url:R,params:f}=this.parseUrl(a);const i=ae(s?.headers??c?.headers);let d=s?.body;if(typeof d==="string"){try{d=JSON.parse(d)}catch{}}const L=i["X-Request-Client"]||i["x-request-client"]||"fetch";const m=()=>({id:r,url:R,method:h,headers:i,data:d,params:f||void 0,client:L});this.emit({type:"request",timestamp:new Date(e.start),request:m()});if(e.requestCopy){void this.readStreamedBody(e.requestCopy).then(({body:l})=>{try{d=JSON.parse(l)}catch{d=l}this.emit({type:"request-body",timestamp:new Date,request:{id:r,url:R,method:h,data:d,client:L}})}).catch(()=>{})}void e.settled.then(async({response:l,clone:w,error:n,headersAt:p})=>{if(!l){this.emit({type:"error",timestamp:new Date,duration:p-e.start,request:m(),error:{message:n instanceof Error?n.message:"Network error",stack:n instanceof Error?n.stack:void 0}});return}const{body:b,size:o}=w?await this.processResponseBody(w):{body:Y,size:0};const y=Math.max(0,_()-e.start);const q=p-e.start;const u={};l.headers.forEach((H,X)=>{u[X.toLowerCase()]=H});this.emit({type:"response",timestamp:new Date,duration:y,timings:y>q?{ttfb:q,download:y-q}:void 0,request:m(),response:{status:l.status,statusText:l.statusText,headers:u,body:b,size:o}})})}adoptEarlyXhr(e){const t=B(e.url);if(this.shouldIgnoreUrl(t))return;const s=D("xhr");const c=e.method.toUpperCase();const{url:a,params:r}=this.parseUrl(t);let h=e.body;if(typeof h==="string"){try{h=JSON.parse(h)}catch{}}const R=e.headers["X-Request-Client"]||e.headers["x-request-client"]||"xhr";this.emit({type:"request",timestamp:new Date(e.start),request:{id:s,url:a,method:c,headers:e.headers,data:h,params:r||void 0,client:R}});const f=e.xhr;const i=()=>{const d=(f._buoyEarlyEnd??_())-e.start;this.handleXHRResponse(f,s,a,c,e.headers,h,r,_()-d,false,R)};if(f.readyState===4)i();else f.addEventListener("loadend",i,{once:true})}addListener(e){this.listeners.push(e);return()=>{const t=this.listeners.indexOf(e);if(t>-1){this.listeners.splice(t,1)}}}removeAllListeners(){this.listeners=[]}get isActive(){return this.isListening}get listenerCount(){return this.listeners.length}}let k=null;const z=()=>{if(!k){k=new le}return k};export const networkListener=z;export const startNetworkListener=()=>z().startListening();export const stopNetworkListener=()=>k?.stopListening();export const addNetworkListener=g=>z().addListener(g);export const removeAllNetworkListeners=()=>k?.removeAllListeners();export const isNetworkListening=()=>k?.isActive??false;export const getNetworkListenerCount=()=>k?.listenerCount??0;export const isNetworkInterceptionLive=()=>k?.isInterceptionLive()??false;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
"use strict";import{devToolsStorageKeys as
|
|
1
|
+
"use strict";import{isBuoyRequest as I,devToolsStorageKeys as f,persistentStorage as h}from"@buoy-gg/shared-ui";import{TIER_LIMITS as S}from"@buoy-gg/shared-ui";export const SESSION_ID=`${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`;export const MAX_PINNED=25;export const MAX_SAVED=50;export const FREE_TIER_SAVED_LIMIT=S["network.saved"].free;const d=16*1024;const v=512*1024;function l(n){if(!n||typeof n!=="object")return false;const e=n;return typeof e.id==="string"&&typeof e.url==="string"&&!I(e.url)}const k=800;export function flagsForEventId(n,e){if(!e)return{pinned:false,saved:false};const t=n.pinnedLiveIds.has(e);const s=n.savedLiveIds.has(e);if(t||s)return{pinned:t,saved:s};const o=n.records.find(r=>r.event.id===e);return o?{pinned:o.pinned,saved:o.saved}:{pinned:false,saved:false}}const b={records:[],pinnedEvents:[],savedRecords:[],pinnedLiveIds:new Set,savedLiveIds:new Set};function p(n){if(n===void 0||n===null)return{value:n,truncated:false};if(typeof n==="string"){if(n.length<=d)return{value:n,truncated:false};return{value:`${n.slice(0,d)}
|
|
2
2
|
|
|
3
3
|
\u2026 truncated by Buoy (body exceeded ${d} bytes)`,truncated:true}}try{const e=JSON.stringify(n);if(e===void 0)return{value:void 0,truncated:false};if(e.length<=d)return{value:n,truncated:false};return{value:`${e.slice(0,d)}
|
|
4
4
|
|
|
5
|
-
\u2026 truncated by Buoy (body exceeded ${d} bytes)`,truncated:true}}catch{return{value:"[unserializable body]",truncated:true}}}function m(n){const e=p(n.requestData);const t=p(n.responseData);if(!e.truncated&&!t.truncated){return{event:{...n},bodyTruncated:false}}return{event:{...n,requestData:e.value,responseData:t.value},bodyTruncated:true}}function y(n){let e=0;if(n.requestData!=null){e+=Math.min(n.requestSize??0,d)}if(n.responseData!=null){e+=Math.min(n.responseSize??0,d)}return e}function
|
|
5
|
+
\u2026 truncated by Buoy (body exceeded ${d} bytes)`,truncated:true}}catch{return{value:"[unserializable body]",truncated:true}}}function m(n){const e=p(n.requestData);const t=p(n.responseData);if(!e.truncated&&!t.truncated){return{event:{...n},bodyTruncated:false}}return{event:{...n,requestData:e.value,responseData:t.value},bodyTruncated:true}}function y(n){let e=0;if(n.requestData!=null){e+=Math.min(n.requestSize??0,d)}if(n.responseData!=null){e+=Math.min(n.responseSize??0,d)}return e}function E(n){let e=0;for(const r of n)e+=y(r.event);if(e<=v)return n;const t=[...n].sort((r,i)=>{if(r.pinned!==i.pinned)return r.pinned?-1:1;return i.savedAt-r.savedAt});const s=new Set;let o=0;for(const r of t){const i=y(r.event);if(o+i<=v){o+=i}else{s.add(r.key)}}if(s.size===0)return n;return n.map(r=>s.has(r.key)?{...r,event:{...r.event,requestData:void 0,responseData:void 0},bodyTruncated:true}:r)}function g(n){if(!Array.isArray(n))return[];const e=[];for(const t of n){if(!t||typeof t!=="object")continue;const s=t;if(typeof s.key!=="string")continue;if(!l(s.event))continue;if(!s.pinned&&!s.saved)continue;e.push({key:s.key,event:{...s.event,id:`saved:${s.key}`},pinned:!!s.pinned,saved:!!s.saved,savedAt:typeof s.savedAt==="number"?s.savedAt:0,sessionId:typeof s.sessionId==="string"?s.sessionId:"unknown",liveId:typeof s.liveId==="string"?s.liveId:"",bodyTruncated:!!s.bodyTruncated})}return e}class T{records=[];listeners=new Set;loaded=false;loadPromise=null;dirty=false;keyCounter=0;trackedLiveIds=new Set;state=b;remote=null;remoteEchoUntil=0;getState(){return this.state}enableRemoteMode(e){this.remote=e}disableRemoteMode(){this.remote=null}replaceRecords(e,t=false){if(!this.remote)return;if(!t&&Date.now()<this.remoteEchoUntil)return;this.records=e.filter(s=>l(s.event));this.rebuild();this.emit()}sessionMatches(e){return this.remote!==null||e.sessionId===SESSION_ID}getRecords(){return this.records}subscribe(e){this.listeners.add(e);void this.ensureLoaded();return()=>{this.listeners.delete(e)}}getEventById(e){for(const t of this.records){if(t.event.id===e)return t.event}return null}isPinned(e){return this.state.pinnedLiveIds.has(e)}isSaved(e){return this.state.savedLiveIds.has(e)}syncFromLive(e){if(this.trackedLiveIds.size===0)return;if(!this.trackedLiveIds.has(e.id))return;const t=this.records.findIndex(o=>this.sessionMatches(o)&&o.liveId===e.id);if(t===-1)return;const s=m(e);this.commit(this.records.map((o,r)=>r===t?{...o,event:s.event,bodyTruncated:s.bodyTruncated}:o))}togglePin(e){return this.setFlag(e,"pinned")}toggleSave(e){return this.setFlag(e,"saved")}remove(e){if(!this.records.some(t=>t.key===e))return;this.remote?.removeRecord(e);this.commit(this.records.filter(t=>t.key!==e))}clearSaved(){if(!this.records.some(e=>e.saved))return;this.remote?.clearSaved();this.commit(this.records.filter(e=>e.pinned).map(e=>({...e,saved:false})))}clearPinned(){if(!this.records.some(e=>e.pinned))return;this.remote?.clearPinned();this.commit(this.records.filter(e=>e.saved).map(e=>({...e,pinned:false})))}setFlag(e,t){if(!l(e))return{ok:false,reason:"invalid-event"};const s=this.findRecordFor(e);if(this.remote){const a=s?!s[t]:true;if(t==="pinned")this.remote.setPinned(e.id,a);else this.remote.setSaved(e.id,a);this.remoteEchoUntil=Date.now()+k}if(s){const a=!s[t];if(a&&!this.hasRoomFor(t,s.key)){return{ok:false,reason:t==="pinned"?"pin-cap":"saved-cap"}}const u={...s,[t]:a};this.commit(u.pinned||u.saved?this.records.map(c=>c.key===s.key?u:c):this.records.filter(c=>c.key!==s.key));return{ok:true,active:a}}if(!this.hasRoomFor(t,null)){return{ok:false,reason:t==="pinned"?"pin-cap":"saved-cap"}}const o=Date.now();const r=m(e);const i={key:`${SESSION_ID}_${++this.keyCounter}`,event:r.event,pinned:t==="pinned",saved:t==="saved",savedAt:o,sessionId:SESSION_ID,liveId:e.id,bodyTruncated:r.bodyTruncated};this.commit(this.evictIfNeeded([i,...this.records]));return{ok:true,active:true}}findRecordFor(e){return this.records.find(t=>t.event.id===e.id||this.sessionMatches(t)&&t.liveId===e.id)}hasRoomFor(e,t){const s=e==="pinned"?MAX_PINNED:MAX_SAVED;const o=this.records.filter(r=>r[e]&&r.key!==t).length;return o<s}evictIfNeeded(e){const t=e.filter(r=>r.saved);if(t.length<=MAX_SAVED)return e;const s=t.filter(r=>!r.pinned).sort((r,i)=>r.savedAt-i.savedAt).slice(0,t.length-MAX_SAVED);if(s.length===0)return e;const o=new Set(s.map(r=>r.key));return e.filter(r=>!o.has(r.key))}ensureLoaded(){if(this.remote)return Promise.resolve();if(this.loaded)return Promise.resolve();if(this.loadPromise)return this.loadPromise;this.loadPromise=(async()=>{try{const e=await h.getItem(f.network.saved());if(e&&!this.dirty){this.records=g(JSON.parse(e));this.rebuild()}}catch{}finally{this.loaded=true;this.emit()}})();return this.loadPromise}persist(){if(this.remote)return;h.setItem(f.network.saved(),JSON.stringify(this.records)).catch(()=>{})}commit(e){this.dirty=true;this.records=E(e);this.rebuild();this.emit();this.persist()}rebuild(){const e=[];const t=[];const s=new Set;const o=new Set;const r=new Set;for(const i of this.records){if(i.pinned)e.push(i);if(i.saved)t.push(i);if(!this.sessionMatches(i)||!i.liveId)continue;r.add(i.liveId);if(i.pinned)s.add(i.liveId);if(i.saved)o.add(i.liveId)}this.trackedLiveIds=r;this.state={records:this.records,pinnedEvents:e.map(i=>i.event),savedRecords:t,pinnedLiveIds:s,savedLiveIds:o}}emit(){this.listeners.forEach(e=>e())}}export const networkSavedStore=new T;
|
|
@@ -30,6 +30,7 @@ export type NetworkEventCallback = (event: NetworkEvent) => void;
|
|
|
30
30
|
*/
|
|
31
31
|
export type NetworkEventsArrayCallback = (events: NetworkEvent[]) => void;
|
|
32
32
|
declare class NetworkEventStore extends BaseEventStore<NetworkEvent> {
|
|
33
|
+
replaceEvents(events: NetworkEvent[]): void;
|
|
33
34
|
private pendingRequests;
|
|
34
35
|
private rawListenerUnsubscribe;
|
|
35
36
|
/** Raw events captured before the first consumer subscribed — see startBootCapture. */
|