@runtimescope/sdk 0.9.1 → 0.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +5 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -1
- package/dist/index.d.ts +33 -1
- package/dist/index.global.js +5 -2
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -35,6 +35,7 @@ interface ConsoleEvent extends BaseEvent {
|
|
|
35
35
|
args: unknown[];
|
|
36
36
|
stackTrace?: string;
|
|
37
37
|
sourceFile?: string;
|
|
38
|
+
source?: 'browser' | 'server' | 'workers';
|
|
38
39
|
}
|
|
39
40
|
interface BuildMeta {
|
|
40
41
|
gitCommit?: string;
|
|
@@ -142,6 +143,9 @@ interface UserContext {
|
|
|
142
143
|
[key: string]: unknown;
|
|
143
144
|
}
|
|
144
145
|
interface RuntimeScopeConfig {
|
|
146
|
+
/** DSN connection string — replaces separate projectId + endpoint + appName fields.
|
|
147
|
+
* Format: runtimescope://proj_abc123@localhost:9091/my-app */
|
|
148
|
+
dsn?: string;
|
|
145
149
|
enabled?: boolean;
|
|
146
150
|
serverUrl?: string;
|
|
147
151
|
/** Alias for `serverUrl` — used by script-tag snippets */
|
|
@@ -160,6 +164,8 @@ interface RuntimeScopeConfig {
|
|
|
160
164
|
captureRenders?: boolean;
|
|
161
165
|
captureNavigation?: boolean;
|
|
162
166
|
captureClicks?: boolean;
|
|
167
|
+
/** Capture uncaught errors and unhandled promise rejections (default: true). */
|
|
168
|
+
captureErrors?: boolean;
|
|
163
169
|
stores?: Record<string, unknown>;
|
|
164
170
|
beforeSend?: (event: RuntimeEvent) => RuntimeEvent | null;
|
|
165
171
|
redactHeaders?: string[];
|
|
@@ -178,6 +184,32 @@ interface RuntimeScopeConfig {
|
|
|
178
184
|
user?: UserContext;
|
|
179
185
|
}
|
|
180
186
|
|
|
187
|
+
/**
|
|
188
|
+
* DSN (Data Source Name) parser for RuntimeScope browser SDK.
|
|
189
|
+
*
|
|
190
|
+
* Format: runtimescope://proj_abc123@localhost:9091/my-app
|
|
191
|
+
* - runtimescope:// or runtimescopes:// (TLS)
|
|
192
|
+
* - projectId before @
|
|
193
|
+
* - host:port after @ (HTTP API port, default 9091)
|
|
194
|
+
* - WS port = HTTP port - 1 (so 9091 → ws on 9090)
|
|
195
|
+
* - Optional /appName path
|
|
196
|
+
*/
|
|
197
|
+
interface ParsedDsn {
|
|
198
|
+
projectId: string;
|
|
199
|
+
wsEndpoint: string;
|
|
200
|
+
httpEndpoint: string;
|
|
201
|
+
appName?: string;
|
|
202
|
+
tls: boolean;
|
|
203
|
+
}
|
|
204
|
+
declare function parseDsn(dsn: string): ParsedDsn;
|
|
205
|
+
declare function buildDsn(opts: {
|
|
206
|
+
projectId: string;
|
|
207
|
+
host?: string;
|
|
208
|
+
port?: number;
|
|
209
|
+
appName?: string;
|
|
210
|
+
tls?: boolean;
|
|
211
|
+
}): string;
|
|
212
|
+
|
|
181
213
|
declare class RuntimeScope {
|
|
182
214
|
private static transport;
|
|
183
215
|
private static restoreFns;
|
|
@@ -219,4 +251,4 @@ declare class RuntimeScope {
|
|
|
219
251
|
static disconnect(): void;
|
|
220
252
|
}
|
|
221
253
|
|
|
222
|
-
export { type BuildMeta, type ConsoleEvent, type CustomEvent, type DomSnapshotEvent, type NavigationEvent, type NetworkEvent, type PerformanceEvent, type RenderEvent, type RuntimeEvent, RuntimeScope, type RuntimeScopeConfig, type SessionEvent, type StateEvent, type UIInteractionEvent, type UserContext, RuntimeScope as default };
|
|
254
|
+
export { type BuildMeta, type ConsoleEvent, type CustomEvent, type DomSnapshotEvent, type NavigationEvent, type NetworkEvent, type ParsedDsn, type PerformanceEvent, type RenderEvent, type RuntimeEvent, RuntimeScope, type RuntimeScopeConfig, type SessionEvent, type StateEvent, type UIInteractionEvent, type UserContext, buildDsn, RuntimeScope as default, parseDsn };
|
package/dist/index.d.ts
CHANGED
|
@@ -35,6 +35,7 @@ interface ConsoleEvent extends BaseEvent {
|
|
|
35
35
|
args: unknown[];
|
|
36
36
|
stackTrace?: string;
|
|
37
37
|
sourceFile?: string;
|
|
38
|
+
source?: 'browser' | 'server' | 'workers';
|
|
38
39
|
}
|
|
39
40
|
interface BuildMeta {
|
|
40
41
|
gitCommit?: string;
|
|
@@ -142,6 +143,9 @@ interface UserContext {
|
|
|
142
143
|
[key: string]: unknown;
|
|
143
144
|
}
|
|
144
145
|
interface RuntimeScopeConfig {
|
|
146
|
+
/** DSN connection string — replaces separate projectId + endpoint + appName fields.
|
|
147
|
+
* Format: runtimescope://proj_abc123@localhost:9091/my-app */
|
|
148
|
+
dsn?: string;
|
|
145
149
|
enabled?: boolean;
|
|
146
150
|
serverUrl?: string;
|
|
147
151
|
/** Alias for `serverUrl` — used by script-tag snippets */
|
|
@@ -160,6 +164,8 @@ interface RuntimeScopeConfig {
|
|
|
160
164
|
captureRenders?: boolean;
|
|
161
165
|
captureNavigation?: boolean;
|
|
162
166
|
captureClicks?: boolean;
|
|
167
|
+
/** Capture uncaught errors and unhandled promise rejections (default: true). */
|
|
168
|
+
captureErrors?: boolean;
|
|
163
169
|
stores?: Record<string, unknown>;
|
|
164
170
|
beforeSend?: (event: RuntimeEvent) => RuntimeEvent | null;
|
|
165
171
|
redactHeaders?: string[];
|
|
@@ -178,6 +184,32 @@ interface RuntimeScopeConfig {
|
|
|
178
184
|
user?: UserContext;
|
|
179
185
|
}
|
|
180
186
|
|
|
187
|
+
/**
|
|
188
|
+
* DSN (Data Source Name) parser for RuntimeScope browser SDK.
|
|
189
|
+
*
|
|
190
|
+
* Format: runtimescope://proj_abc123@localhost:9091/my-app
|
|
191
|
+
* - runtimescope:// or runtimescopes:// (TLS)
|
|
192
|
+
* - projectId before @
|
|
193
|
+
* - host:port after @ (HTTP API port, default 9091)
|
|
194
|
+
* - WS port = HTTP port - 1 (so 9091 → ws on 9090)
|
|
195
|
+
* - Optional /appName path
|
|
196
|
+
*/
|
|
197
|
+
interface ParsedDsn {
|
|
198
|
+
projectId: string;
|
|
199
|
+
wsEndpoint: string;
|
|
200
|
+
httpEndpoint: string;
|
|
201
|
+
appName?: string;
|
|
202
|
+
tls: boolean;
|
|
203
|
+
}
|
|
204
|
+
declare function parseDsn(dsn: string): ParsedDsn;
|
|
205
|
+
declare function buildDsn(opts: {
|
|
206
|
+
projectId: string;
|
|
207
|
+
host?: string;
|
|
208
|
+
port?: number;
|
|
209
|
+
appName?: string;
|
|
210
|
+
tls?: boolean;
|
|
211
|
+
}): string;
|
|
212
|
+
|
|
181
213
|
declare class RuntimeScope {
|
|
182
214
|
private static transport;
|
|
183
215
|
private static restoreFns;
|
|
@@ -219,4 +251,4 @@ declare class RuntimeScope {
|
|
|
219
251
|
static disconnect(): void;
|
|
220
252
|
}
|
|
221
253
|
|
|
222
|
-
export { type BuildMeta, type ConsoleEvent, type CustomEvent, type DomSnapshotEvent, type NavigationEvent, type NetworkEvent, type PerformanceEvent, type RenderEvent, type RuntimeEvent, RuntimeScope, type RuntimeScopeConfig, type SessionEvent, type StateEvent, type UIInteractionEvent, type UserContext, RuntimeScope as default };
|
|
254
|
+
export { type BuildMeta, type ConsoleEvent, type CustomEvent, type DomSnapshotEvent, type NavigationEvent, type NetworkEvent, type ParsedDsn, type PerformanceEvent, type RenderEvent, type RuntimeEvent, RuntimeScope, type RuntimeScopeConfig, type SessionEvent, type StateEvent, type UIInteractionEvent, type UserContext, buildDsn, RuntimeScope as default, parseDsn };
|
package/dist/index.global.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
"use strict";var RuntimeScope=(()=>{var M=Object.defineProperty;var ie=Object.getOwnPropertyDescriptor;var ae=Object.getOwnPropertyNames;var ce=Object.prototype.hasOwnProperty;var ue=(t,e,s)=>e in t?M(t,e,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[e]=s;var de=(t,e)=>{for(var s in e)M(t,s,{get:e[s],enumerable:!0})},le=(t,e,s,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of ae(e))!ce.call(t,r)&&r!==s&&M(t,r,{get:()=>e[r],enumerable:!(n=ie(e,r))||n.enumerable});return t};var pe=t=>le(M({},"__esModule",{value:!0}),t);var p=(t,e,s)=>ue(t,typeof e!="symbol"?e+"":e,s);var Xe={};de(Xe,{RuntimeScope:()=>E,default:()=>Ue});var k=console.debug.bind(console),R=class R{constructor(e){p(this,"ws",null);p(this,"batch",[]);p(this,"offlineQueue",[]);p(this,"flushTimer",null);p(this,"reconnectTimer",null);p(this,"reconnectDelay",500);p(this,"reconnectAttempt",0);p(this,"connected",!1);p(this,"stopped",!1);p(this,"config");p(this,"commandHandler",null);p(this,"hasEverConnected",!1);p(this,"connectionWarningTimer",null);p(this,"visibilityHandler",null);p(this,"onlineHandler",null);this.config=e}connect(){this.stopped=!1,this.doConnect(),this.connectionWarningTimer=setTimeout(()=>{!this.hasEverConnected&&!this.stopped&&console.warn(`[RuntimeScope] SDK has not connected to ${this.config.serverUrl} after 10s. Is the collector running? Start it with: npx @runtimescope/collector`)},R.CONNECTION_WARNING_DELAY),typeof document<"u"&&(this.visibilityHandler=()=>{document.visibilityState==="visible"&&!this.connected&&!this.stopped&&(k("[RuntimeScope] Tab visible \u2014 attempting immediate reconnect"),this.resetReconnectState(),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.doConnect())},document.addEventListener("visibilitychange",this.visibilityHandler)),typeof window<"u"&&(this.onlineHandler=()=>{!this.connected&&!this.stopped&&(k("[RuntimeScope] Network online \u2014 attempting immediate reconnect"),this.resetReconnectState(),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.doConnect())},window.addEventListener("online",this.onlineHandler))}doConnect(){if(!this.stopped){try{this.ws=new WebSocket(this.config.serverUrl)}catch{this.scheduleReconnect();return}this.ws.onmessage=e=>{try{let s=JSON.parse(String(e.data));s.type==="command"&&s.payload&&this.commandHandler&&this.commandHandler(s.payload),s.type==="__server_restart"&&(k("[RuntimeScope] Server restart notice received \u2014 will reconnect immediately"),this.resetReconnectState()),s.type==="error"&&s.payload?.code==="AUTH_FAILED"&&(k("[RuntimeScope] Authentication failed \u2014 stopping reconnection"),this.stopped=!0)}catch{}},this.ws.onopen=()=>{if(this.connected=!0,this.hasEverConnected=!0,this.resetReconnectState(),k(`[RuntimeScope] Connected to ${this.config.serverUrl}`),this.sendRaw({type:"handshake",payload:{appName:this.config.appName,sdkVersion:this.config.sdkVersion,sessionId:this.config.sessionId,...this.config.authToken?{authToken:this.config.authToken}:{},...this.config.projectId?{projectId:this.config.projectId}:{}},timestamp:Date.now(),sessionId:this.config.sessionId}),this.offlineQueue.length>0){let e=this.offlineQueue.splice(0);for(let s of e)this.batch.push(s);this.flush()}this.flushTimer=setInterval(()=>this.flush(),this.config.flushIntervalMs)},this.ws.onclose=()=>{this.connected=!1,this.clearFlushTimer(),this.stopped||(k("[RuntimeScope] Disconnected, will reconnect..."),this.scheduleReconnect())},this.ws.onerror=()=>{k(`[RuntimeScope] WebSocket error connecting to ${this.config.serverUrl}`)}}}send(e){this.connected?(this.batch.push(e),this.batch.length>=this.config.batchSize&&this.flush()):this.offlineQueue.length<R.MAX_OFFLINE_QUEUE&&this.offlineQueue.push(e)}flush(){if(this.batch.length===0||!this.connected||!this.ws)return;let e=this.batch.splice(0);this.sendRaw({type:"event",payload:{events:e},timestamp:Date.now(),sessionId:this.config.sessionId})}sendRaw(e){if(this.ws&&this.ws.readyState===WebSocket.OPEN)try{this.ws.send(JSON.stringify(e))}catch{}}scheduleReconnect(){if(this.stopped||this.reconnectTimer)return;this.reconnectAttempt++;let e;if(this.reconnectAttempt<=R.FAST_RETRY_COUNT)e=R.FAST_RETRY_DELAY;else{let s=this.reconnectDelay*.25*(Math.random()*2-1);e=Math.min(this.reconnectDelay+s,R.MAX_RECONNECT_DELAY),this.reconnectDelay=Math.min(this.reconnectDelay*2,R.MAX_RECONNECT_DELAY)}this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.doConnect()},e)}resetReconnectState(){this.reconnectDelay=500,this.reconnectAttempt=0}clearFlushTimer(){this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null)}onCommand(e){this.commandHandler=e}sendCommandResponse(e,s,n){this.sendRaw({type:"command_response",requestId:e,command:s,payload:n,timestamp:Date.now(),sessionId:this.config.sessionId})}disconnect(){this.stopped=!0,this.clearFlushTimer(),this.connectionWarningTimer&&(clearTimeout(this.connectionWarningTimer),this.connectionWarningTimer=null),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.visibilityHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null),this.onlineHandler&&typeof window<"u"&&(window.removeEventListener("online",this.onlineHandler),this.onlineHandler=null),this.flush(),this.ws&&(this.ws.onclose=null,this.ws.onerror=null,this.ws.close(),this.ws=null),this.connected=!1,this.batch=[],this.offlineQueue=[]}};p(R,"MAX_OFFLINE_QUEUE",1e3),p(R,"MAX_RECONNECT_DELAY",3e4),p(R,"CONNECTION_WARNING_DELAY",1e4),p(R,"FAST_RETRY_COUNT",3),p(R,"FAST_RETRY_DELAY",500);var F=R;function m(){let t=new Uint8Array(8);return crypto.getRandomValues(t),Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}function $(){let t=new Uint8Array(16);return crypto.getRandomValues(t),Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}var fe=1e3,me=1e4,he=5e3,C=new Map,H=null,P=0;function ve(){P++,!H&&(H=setInterval(()=>{let t=Date.now()-me;for(let[e,s]of C)s<t&&C.delete(e)},he))}function ge(){P--,P<=0&&H&&(clearInterval(H),H=null,P=0)}function W(t,e,s,n){let r=window.fetch,c=new Set(s.map(a=>a.toLowerCase())),i=n?.captureBody??!1,o=n?.maxBodySize??65536;return ve(),window.fetch=async function(a,u){let d=performance.now(),l=typeof a=="string"?a:a instanceof URL?a.href:a.url,f=(u?.method??"GET").toUpperCase(),b=ye(u?.headers,c),g=Re(u?.body),T=Se(u?.body),x;i&&u?.body&&(x=Ee(u.body,o));let j=`${f}:${l}:${d}`;if(C.size>=fe){let h=C.keys().next().value;h!==void 0&&C.delete(h)}C.set(j,Date.now());try{let h=await r.call(window,a,u),_=performance.now()-d,L=parseInt(h.headers.get("content-length")||"0",10),I=we(h.headers,c),v;if(i)try{let O=await h.clone().text();v=O.length>o?O.slice(0,o):O}catch{}let w={eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"network",url:l,method:f,status:h.status,requestHeaders:b,responseHeaders:I,requestBodySize:g,responseBodySize:L,duration:_,ttfb:_,graphqlOperation:T,requestBody:x,responseBody:v,source:"fetch"};if(n?.beforeSend){let S=n.beforeSend(w);S&&t(S)}else t(w);return h}catch(h){let _=performance.now()-d,L="error",I="";h instanceof DOMException&&h.name==="AbortError"?(L="abort",I="Request aborted"):h instanceof Error&&(I=h.message);let v={eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"network",url:l,method:f,status:0,requestHeaders:b,responseHeaders:{},requestBodySize:g,responseBodySize:0,duration:_,ttfb:0,graphqlOperation:T,requestBody:x,errorPhase:L,errorMessage:I,source:"fetch"};if(n?.beforeSend){let w=n.beforeSend(v);w&&t(w)}else t(v);throw h}},()=>{window.fetch=r,ge()}}function ye(t,e){let s={};if(!t)return s;if(t instanceof Headers)t.forEach((n,r)=>{s[r]=e.has(r.toLowerCase())?"[REDACTED]":n});else if(Array.isArray(t))for(let[n,r]of t)s[n]=e.has(n.toLowerCase())?"[REDACTED]":r;else for(let[n,r]of Object.entries(t))s[n]=e.has(n.toLowerCase())?"[REDACTED]":r;return s}function we(t,e){let s={};return t.forEach((n,r)=>{s[r]=e.has(r.toLowerCase())?"[REDACTED]":n}),s}function Re(t){return t?typeof t=="string"?new Blob([t]).size:t instanceof Blob?t.size:t instanceof ArrayBuffer||ArrayBuffer.isView(t)?t.byteLength:t instanceof FormData?0:t instanceof URLSearchParams?new Blob([t.toString()]).size:0:0}function Ee(t,e){if(t){if(typeof t=="string")return t.length>e?t.slice(0,e):t;if(t instanceof URLSearchParams){let s=t.toString();return s.length>e?s.slice(0,e):s}if(t instanceof FormData)return"[FormData]";if(t instanceof Blob)return`[Blob ${t.size} bytes]`;if(t instanceof ArrayBuffer)return`[ArrayBuffer ${t.byteLength} bytes]`;if(ArrayBuffer.isView(t))return`[TypedArray ${t.byteLength} bytes]`}}function Se(t){if(!(!t||typeof t!="string"))try{let e=JSON.parse(t);if(typeof e.query=="string"){let s=e.query.trim(),n="query";s.startsWith("mutation")?n="mutation":s.startsWith("subscription")&&(n="subscription");let r=e.operationName||be(s)||"anonymous";return{type:n,name:r}}}catch{}}function be(t){return t.match(/^(?:query|mutation|subscription)\s+(\w+)/)?.[1]}function y(t,e=5){let s=new WeakSet;function n(r,c){if(c>e)return"[max depth]";if(r==null)return r;if(typeof r=="function")return`[Function: ${r.name||"anonymous"}]`;if(typeof r=="symbol"||typeof r=="bigint")return r.toString();if(typeof r!="object")return r;if(r instanceof Error)return{name:r.name,message:r.message,stack:r.stack};if(r instanceof Date)return r.toISOString();if(r instanceof RegExp)return r.toString();if(s.has(r))return"[Circular]";if(s.add(r),Array.isArray(r))return r.map(u=>n(u,c+1));let i={},o;try{o=Object.keys(r)}catch{return"[Object]"}let a=50;for(let u=0;u<Math.min(o.length,a);u++)try{i[o[u]]=n(r[o[u]],c+1)}catch{i[o[u]]="[Error accessing property]"}return o.length>a&&(i["..."]=`${o.length-a} more keys`),i}return n(t,0)}var V=["log","warn","error","info","debug","trace"];function G(t,e,s){let n={};for(let r of V)n[r]=console[r].bind(console),console[r]=(...c)=>{let i=c.map(a=>typeof a=="string"?a:_e(a)).join(" "),o={eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"console",level:r,message:i,args:c.map(a=>y(a,3)),stackTrace:r==="error"||r==="trace"?new Error().stack?.split(`
|
|
1
|
+
"use strict";var RuntimeScope=(()=>{var M=Object.defineProperty;var de=Object.getOwnPropertyDescriptor;var pe=Object.getOwnPropertyNames;var le=Object.prototype.hasOwnProperty;var fe=(t,e,r)=>e in t?M(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var me=(t,e)=>{for(var r in e)M(t,r,{get:e[r],enumerable:!0})},he=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of pe(e))!le.call(t,n)&&n!==r&&M(t,n,{get:()=>e[n],enumerable:!(s=de(e,n))||s.enumerable});return t};var ge=t=>he(M({},"__esModule",{value:!0}),t);var f=(t,e,r)=>fe(t,typeof e!="symbol"?e+"":e,r);var Ve={};me(Ve,{RuntimeScope:()=>b,buildDsn:()=>ue,default:()=>We,parseDsn:()=>$});var D=console.debug.bind(console),S=class S{constructor(e){f(this,"ws",null);f(this,"batch",[]);f(this,"offlineQueue",[]);f(this,"flushTimer",null);f(this,"reconnectTimer",null);f(this,"reconnectDelay",500);f(this,"reconnectAttempt",0);f(this,"connected",!1);f(this,"stopped",!1);f(this,"config");f(this,"commandHandler",null);f(this,"hasEverConnected",!1);f(this,"connectionWarningTimer",null);f(this,"visibilityHandler",null);f(this,"onlineHandler",null);this.config=e}connect(){this.stopped=!1,this.doConnect(),this.connectionWarningTimer=setTimeout(()=>{!this.hasEverConnected&&!this.stopped&&console.warn(`[RuntimeScope] SDK has not connected to ${this.config.serverUrl} after 10s. Is the collector running? Start it with: npx @runtimescope/collector`)},S.CONNECTION_WARNING_DELAY),typeof document<"u"&&(this.visibilityHandler=()=>{document.visibilityState==="visible"&&!this.connected&&!this.stopped&&(D("[RuntimeScope] Tab visible \u2014 attempting immediate reconnect"),this.resetReconnectState(),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.doConnect())},document.addEventListener("visibilitychange",this.visibilityHandler)),typeof window<"u"&&(this.onlineHandler=()=>{!this.connected&&!this.stopped&&(D("[RuntimeScope] Network online \u2014 attempting immediate reconnect"),this.resetReconnectState(),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.doConnect())},window.addEventListener("online",this.onlineHandler))}doConnect(){if(!this.stopped){try{this.ws=new WebSocket(this.config.serverUrl)}catch{this.scheduleReconnect();return}this.ws.onmessage=e=>{try{let r=JSON.parse(String(e.data));r.type==="command"&&r.payload&&this.commandHandler&&this.commandHandler(r.payload),r.type==="__server_restart"&&(D("[RuntimeScope] Server restart notice received \u2014 will reconnect immediately"),this.resetReconnectState()),r.type==="error"&&r.payload?.code==="AUTH_FAILED"&&(D("[RuntimeScope] Authentication failed \u2014 stopping reconnection"),this.stopped=!0)}catch{}},this.ws.onopen=()=>{if(this.connected=!0,this.hasEverConnected=!0,this.resetReconnectState(),D(`[RuntimeScope] Connected to ${this.config.serverUrl}`),this.sendRaw({type:"handshake",payload:{appName:this.config.appName,sdkVersion:this.config.sdkVersion,sessionId:this.config.sessionId,...this.config.authToken?{authToken:this.config.authToken}:{},...this.config.projectId?{projectId:this.config.projectId}:{}},timestamp:Date.now(),sessionId:this.config.sessionId}),this.offlineQueue.length>0){let e=this.offlineQueue.splice(0);for(let r of e)this.batch.push(r);this.flush()}this.flushTimer=setInterval(()=>this.flush(),this.config.flushIntervalMs)},this.ws.onclose=()=>{this.connected=!1,this.clearFlushTimer(),this.stopped||(D("[RuntimeScope] Disconnected, will reconnect..."),this.scheduleReconnect())},this.ws.onerror=()=>{D(`[RuntimeScope] WebSocket error connecting to ${this.config.serverUrl}`)}}}send(e){this.connected?(this.batch.push(e),this.batch.length>=this.config.batchSize&&this.flush()):this.offlineQueue.length<S.MAX_OFFLINE_QUEUE&&this.offlineQueue.push(e)}flush(){if(this.batch.length===0||!this.connected||!this.ws)return;let e=this.batch.splice(0);this.sendRaw({type:"event",payload:{events:e},timestamp:Date.now(),sessionId:this.config.sessionId})}sendRaw(e){if(this.ws&&this.ws.readyState===WebSocket.OPEN)try{this.ws.send(JSON.stringify(e))}catch{}}scheduleReconnect(){if(this.stopped||this.reconnectTimer)return;this.reconnectAttempt++;let e;if(this.reconnectAttempt<=S.FAST_RETRY_COUNT)e=S.FAST_RETRY_DELAY;else{let r=this.reconnectDelay*.25*(Math.random()*2-1);e=Math.min(this.reconnectDelay+r,S.MAX_RECONNECT_DELAY),this.reconnectDelay=Math.min(this.reconnectDelay*2,S.MAX_RECONNECT_DELAY)}this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.doConnect()},e)}resetReconnectState(){this.reconnectDelay=500,this.reconnectAttempt=0}clearFlushTimer(){this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null)}onCommand(e){this.commandHandler=e}sendCommandResponse(e,r,s){this.sendRaw({type:"command_response",requestId:e,command:r,payload:s,timestamp:Date.now(),sessionId:this.config.sessionId})}disconnect(){this.stopped=!0,this.clearFlushTimer(),this.connectionWarningTimer&&(clearTimeout(this.connectionWarningTimer),this.connectionWarningTimer=null),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.visibilityHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null),this.onlineHandler&&typeof window<"u"&&(window.removeEventListener("online",this.onlineHandler),this.onlineHandler=null),this.flush(),this.ws&&(this.ws.onclose=null,this.ws.onerror=null,this.ws.close(),this.ws=null),this.connected=!1,this.batch=[],this.offlineQueue=[]}};f(S,"MAX_OFFLINE_QUEUE",1e3),f(S,"MAX_RECONNECT_DELAY",3e4),f(S,"CONNECTION_WARNING_DELAY",1e4),f(S,"FAST_RETRY_COUNT",3),f(S,"FAST_RETRY_DELAY",500);var P=S;function m(){let t=new Uint8Array(8);return crypto.getRandomValues(t),Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}function W(){let t=new Uint8Array(16);return crypto.getRandomValues(t),Array.from(t,e=>e.toString(16).padStart(2,"0")).join("")}var ve=1e3,we=1e4,ye=5e3,L=new Map,H=null,B=0;function Ee(){B++,!H&&(H=setInterval(()=>{let t=Date.now()-we;for(let[e,r]of L)r<t&&L.delete(e)},ye))}function Re(){B--,B<=0&&H&&(clearInterval(H),H=null,B=0)}function V(t,e,r,s){let n=window.fetch,c=new Set(r.map(o=>o.toLowerCase())),a=s?.captureBody??!1,i=s?.maxBodySize??65536;return Ee(),window.fetch=async function(o,u){let p=performance.now(),l=typeof o=="string"?o:o instanceof URL?o.href:o.url,d=(u?.method??"GET").toUpperCase(),h=Se(u?.headers,c),g=_e(u?.body),_=Ie(u?.body),E;a&&u?.body&&(E=Te(u.body,i));let T=`${d}:${l}:${p}`;if(L.size>=ve){let v=L.keys().next().value;v!==void 0&&L.delete(v)}L.set(T,Date.now());try{let v=await n.call(window,o,u),k=performance.now()-p,x=parseInt(v.headers.get("content-length")||"0",10),C=be(v.headers,c),w;if(a)try{let O=await v.clone().text();w=O.length>i?O.slice(0,i):O}catch{}let R={eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"network",url:l,method:d,status:v.status,requestHeaders:h,responseHeaders:C,requestBodySize:g,responseBodySize:x,duration:k,ttfb:k,graphqlOperation:_,requestBody:E,responseBody:w,source:"fetch"};if(s?.beforeSend){let I=s.beforeSend(R);I&&t(I)}else t(R);return v}catch(v){let k=performance.now()-p,x="error",C="";v instanceof DOMException&&v.name==="AbortError"?(x="abort",C="Request aborted"):v instanceof Error&&(C=v.message);let w={eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"network",url:l,method:d,status:0,requestHeaders:h,responseHeaders:{},requestBodySize:g,responseBodySize:0,duration:k,ttfb:0,graphqlOperation:_,requestBody:E,errorPhase:x,errorMessage:C,source:"fetch"};if(s?.beforeSend){let R=s.beforeSend(w);R&&t(R)}else t(w);throw v}},()=>{window.fetch=n,Re()}}function Se(t,e){let r={};if(!t)return r;if(t instanceof Headers)t.forEach((s,n)=>{r[n]=e.has(n.toLowerCase())?"[REDACTED]":s});else if(Array.isArray(t))for(let[s,n]of t)r[s]=e.has(s.toLowerCase())?"[REDACTED]":n;else for(let[s,n]of Object.entries(t))r[s]=e.has(s.toLowerCase())?"[REDACTED]":n;return r}function be(t,e){let r={};return t.forEach((s,n)=>{r[n]=e.has(n.toLowerCase())?"[REDACTED]":s}),r}function _e(t){return t?typeof t=="string"?new Blob([t]).size:t instanceof Blob?t.size:t instanceof ArrayBuffer||ArrayBuffer.isView(t)?t.byteLength:t instanceof FormData?0:t instanceof URLSearchParams?new Blob([t.toString()]).size:0:0}function Te(t,e){if(t){if(typeof t=="string")return t.length>e?t.slice(0,e):t;if(t instanceof URLSearchParams){let r=t.toString();return r.length>e?r.slice(0,e):r}if(t instanceof FormData)return"[FormData]";if(t instanceof Blob)return`[Blob ${t.size} bytes]`;if(t instanceof ArrayBuffer)return`[ArrayBuffer ${t.byteLength} bytes]`;if(ArrayBuffer.isView(t))return`[TypedArray ${t.byteLength} bytes]`}}function Ie(t){if(!(!t||typeof t!="string"))try{let e=JSON.parse(t);if(typeof e.query=="string"){let r=e.query.trim(),s="query";r.startsWith("mutation")?s="mutation":r.startsWith("subscription")&&(s="subscription");let n=e.operationName||ke(r)||"anonymous";return{type:s,name:n}}}catch{}}function ke(t){return t.match(/^(?:query|mutation|subscription)\s+(\w+)/)?.[1]}function y(t,e=5){let r=new WeakSet;function s(n,c){if(c>e)return"[max depth]";if(n==null)return n;if(typeof n=="function")return`[Function: ${n.name||"anonymous"}]`;if(typeof n=="symbol"||typeof n=="bigint")return n.toString();if(typeof n!="object")return n;if(n instanceof Error)return{name:n.name,message:n.message,stack:n.stack};if(n instanceof Date)return n.toISOString();if(n instanceof RegExp)return n.toString();if(r.has(n))return"[Circular]";if(r.add(n),Array.isArray(n))return n.map(u=>s(u,c+1));let a={},i;try{i=Object.keys(n)}catch{return"[Object]"}let o=50;for(let u=0;u<Math.min(i.length,o);u++)try{a[i[u]]=s(n[i[u]],c+1)}catch{a[i[u]]="[Error accessing property]"}return i.length>o&&(a["..."]=`${i.length-o} more keys`),a}return s(t,0)}var G=["log","warn","error","info","debug","trace"];function Q(t){if(!t)return;let e=t.split(`
|
|
2
|
+
`).slice(3);for(let r of e){let s=r.match(/(?:at\s+)?(?:.*?\()?(.+?):(\d+):(\d+)\)?/);if(s&&!s[1].includes("interceptor")&&!s[1].includes("runtimescope"))return`${s[1]}:${s[2]}`}}function Y(t,e,r){let s={},n=new Map,c=new Map;for(let d of G)s[d]=console[d].bind(console),console[d]=(...h)=>{let g=new Error().stack,_=h.map(T=>typeof T=="string"?T:K(T)).join(" "),E={eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"console",level:d,message:_,args:h.map(T=>y(T,3)),stackTrace:d==="error"||d==="trace"?g?.split(`
|
|
2
3
|
`).slice(2).join(`
|
|
3
|
-
`):void 0,sourceFile:void 0};if(s){let a=s(o);a&&t(a)}else t(o);n[r](...c)};return()=>{for(let r of V)console[r]=n[r]}}function _e(t){try{return JSON.stringify(t)}catch{return String(t)}}function Q(t,e,s,n){let r=new Set(s.map(l=>l.toLowerCase())),c=n?.captureBody??!1,i=n?.maxBodySize??65536,o=new AbortController,a=XMLHttpRequest.prototype.open,u=XMLHttpRequest.prototype.setRequestHeader,d=XMLHttpRequest.prototype.send;return XMLHttpRequest.prototype.open=function(l,f){return this.__rs_method=l.toUpperCase(),this.__rs_url=typeof f=="string"?f:f.href,this.__rs_headers={},a.apply(this,arguments)},XMLHttpRequest.prototype.setRequestHeader=function(l,f){return this.__rs_headers&&(this.__rs_headers[l.toLowerCase()]=r.has(l.toLowerCase())?"[REDACTED]":f),u.call(this,l,f)},XMLHttpRequest.prototype.send=function(l){let f=this.__rs_method??"GET",b=this.__rs_url??"",g=`${f}:${b}`,T=!1;for(let v of C.keys())if(v.startsWith(g)){T=!0;break}if(T)return this.__rs_fetchIntercepted=!0,d.call(this,l);let x={...this.__rs_headers??{}},j=performance.now(),h,_=0;if(l){if(typeof l=="string")_=new Blob([l]).size,c&&(h=l.length>i?l.slice(0,i):l);else if(l instanceof Blob)_=l.size,c&&(h=`[Blob ${l.size} bytes]`);else if(l instanceof ArrayBuffer)_=l.byteLength,c&&(h=`[ArrayBuffer ${l.byteLength} bytes]`);else if(l instanceof FormData)c&&(h="[FormData]");else if(l instanceof URLSearchParams){let v=l.toString();_=new Blob([v]).size,c&&(h=v.length>i?v.slice(0,i):v)}}let L=Ie(l),I=v=>{let w={eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"network",url:b,method:f,status:0,requestHeaders:x,responseHeaders:{},requestBodySize:_,responseBodySize:0,duration:0,ttfb:0,graphqlOperation:L,requestBody:h,source:"xhr",...v};if(n?.beforeSend){let S=n.beforeSend(w);S&&t(S)}else t(w)};return this.addEventListener("loadend",()=>{let v=performance.now()-j;if(this.status>0){let w=Te(this.getAllResponseHeaders(),r),S=parseInt(this.getResponseHeader("content-length")||"0",10),O;if(c&&(this.responseType===""||this.responseType==="text"))try{let U=this.responseText;O=U.length>i?U.slice(0,i):U}catch{}I({status:this.status,responseHeaders:w,responseBodySize:S,responseBody:O,duration:v,ttfb:v})}else{let w="error",S="Network error";this.readyState===0||this.status,this.timeout>0&&v>=this.timeout&&(w="timeout",S=`Request timed out after ${this.timeout}ms`),I({duration:v,errorPhase:w,errorMessage:S})}},{once:!0,signal:o.signal}),d.call(this,l)},()=>{o.abort(),XMLHttpRequest.prototype.open=a,XMLHttpRequest.prototype.setRequestHeader=u,XMLHttpRequest.prototype.send=d}}function Te(t,e){let s={};if(!t)return s;for(let n of t.trim().split(/[\r\n]+/)){let r=n.indexOf(":");if(r===-1)continue;let c=n.slice(0,r).trim().toLowerCase(),i=n.slice(r+1).trim();s[c]=e.has(c)?"[REDACTED]":i}return s}function Ie(t){if(!(!t||typeof t!="string"))try{let e=JSON.parse(t);if(typeof e.query=="string"){let s=e.query.trim(),n="query";s.startsWith("mutation")?n="mutation":s.startsWith("subscription")&&(n="subscription");let r=e.operationName||Ce(s)||"anonymous";return{type:n,name:r}}}catch{}}function Ce(t){return t.match(/^(?:query|mutation|subscription)\s+(\w+)/)?.[1]}function Y(t,e,s,n){let r=[],c=new Map;for(let[i,o]of Object.entries(s)){let a=ke(o);if(a==="zustand"){let u=o;B(t,e,n?.beforeSend,{storeId:i,library:a,phase:"init",state:y(u.getState(),4)});let d=u.subscribe((l,f)=>{let b=K(f,l);B(t,e,n?.beforeSend,{storeId:i,library:a,phase:"update",state:y(l,4),previousState:y(f,4),diff:b?y(b,3):void 0})});r.push(d)}else if(a==="redux"){let u=o;B(t,e,n?.beforeSend,{storeId:i,library:a,phase:"init",state:y(u.getState(),4)});let d,l=u.dispatch.bind(u);c.set(i,l),u.dispatch=g=>(g&&typeof g=="object"&&"type"in g&&(d={type:String(g.type),payload:g.payload}),l(g));let f=u.getState(),b=u.subscribe(()=>{let g=u.getState(),T=K(f,g);B(t,e,n?.beforeSend,{storeId:i,library:a,phase:"update",state:y(g,4),previousState:y(f,4),diff:T?y(T,3):void 0,action:d?y(d,3):void 0}),f=g,d=void 0});r.push(b)}}return()=>{for(let i of r)i();for(let[i,o]of c){let a=s[i];a&&(a.dispatch=o)}}}function ke(t){if(!t||typeof t!="object")return"unknown";let e=t;return typeof e.getState=="function"&&typeof e.setState=="function"&&typeof e.subscribe=="function"?"zustand":typeof e.dispatch=="function"&&typeof e.getState=="function"&&typeof e.subscribe=="function"?"redux":"unknown"}function K(t,e){if(!t||!e||typeof t!="object"||typeof e!="object")return null;let s={},n=t,r=e,c=new Set([...Object.keys(n),...Object.keys(r)]);for(let i of c)n[i]!==r[i]&&(s[i]={from:n[i],to:r[i]});return Object.keys(s).length>0?s:null}function B(t,e,s,n){let r={eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"state",...n};if(s){let c=s(r);c&&t(c)}else t(r)}var Le={LCP:[2500,4e3],FCP:[1800,3e3],CLS:[.1,.25],TTFB:[800,1800],FID:[100,300],INP:[200,500]};function Oe(t,e){let[s,n]=Le[t]??[1/0,1/0];return e<=s?"good":e<=n?"needs-improvement":"poor"}var A=null;function J(t,e,s){if(A)for(let o of A)try{o.disconnect()}catch{}let n=[];A=n;let r=(o,a,u)=>{let d={eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"performance",metricName:o,value:Math.round(a*100)/100,rating:Oe(o,a),element:u};if(s?.beforeSend){let l=s.beforeSend(d);l&&t(l)}else t(d)};N(n,"largest-contentful-paint",o=>{let a=o[o.length-1];if(!a)return;let u=a.element;r("LCP",a.startTime,u?.tagName?.toLowerCase())}),N(n,"paint",o=>{for(let a of o)a.name==="first-contentful-paint"&&r("FCP",a.startTime)});let c=0;N(n,"layout-shift",o=>{for(let a of o){let u=a;!u.hadRecentInput&&u.value&&(c+=u.value,r("CLS",c))}}),N(n,"first-input",o=>{let a=o[0];if(!a)return;let u=a;u.processingStart&&r("FID",u.processingStart-a.startTime)}),N(n,"navigation",o=>{let a=o[0];a&&r("TTFB",a.responseStart-a.requestStart)});let i=0;return N(n,"event",o=>{for(let a of o)a.duration>i&&(i=a.duration,r("INP",i))},{durationThreshold:16}),()=>{for(let o of n)try{o.disconnect()}catch{}A===n&&(A=null)}}function N(t,e,s,n){try{let r=new PerformanceObserver(c=>{s(c.getEntries())});r.observe({type:e,buffered:!0,...n}),t.push(r)}catch{}}var Ne=0,De=1,te=1e4,Z=100,xe=6e4,ee=500;function ne(t,e,s){let n=new Map,r=s?.snapshotIntervalMs??5e3,c=null,i=He();if(!i)return()=>{};let o=i.onCommitFiberRoot;return i._runtimescope_original=o,i.onCommitFiberRoot=(a,u)=>{if(o)try{o(a,u)}catch{}u.current&&X(u.current,n)},c=setInterval(()=>{Be(n,t,e,s?.beforeSend)},r),()=>{c&&(clearInterval(c),c=null),i&&(i._runtimescope_original?i.onCommitFiberRoot=i._runtimescope_original:delete i.onCommitFiberRoot,delete i._runtimescope_original)}}function He(){if(typeof window>"u")return null;let t=window;return t.__REACT_DEVTOOLS_GLOBAL_HOOK__||(t.__REACT_DEVTOOLS_GLOBAL_HOOK__={}),t.__REACT_DEVTOOLS_GLOBAL_HOOK__}function X(t,e){Ae(t,e),t.child&&X(t.child,e),t.sibling&&X(t.sibling,e)}function Ae(t,e){if(t.tag!==Ne&&t.tag!==De)return;let s=Me(t);if(!s)return;let n=Date.now(),r=t.alternate===null,c=t.actualDuration??0,i=Fe(t,r),o=e.get(s);o||(o={renderCount:0,totalDuration:0,lastRenderTime:0,lastRenderPhase:"mount",lastRenderCause:"unknown",renderTimestamps:[]},e.set(s,o)),o.renderCount++,o.totalDuration+=c,o.lastRenderTime=n,o.lastRenderPhase=r?"mount":"update",o.lastRenderCause=i??"unknown",o.renderTimestamps.push(n),o.renderTimestamps.length>Z&&(o.renderTimestamps=o.renderTimestamps.slice(-Z))}function Me(t){if(t.type&&typeof t.type!="string")return t.type.displayName||t.type.name||void 0}function Fe(t,e){return e?"props":t.alternate?t.memoizedProps!==t.alternate.memoizedProps?"props":t.memoizedState!==t.alternate.memoizedState?"state":"parent":"unknown"}function Pe(t){if(t.length<2)return 0;let e=Date.now(),s=e-te,n=t.filter(c=>c>=s);if(n.length<2)return 0;let r=e-n[0];return r===0?0:n.length/(r/1e3)}function Be(t,e,s,n){if(t.size===0)return;let r=[],c=[],i=0;for(let[u,d]of t){let l=Pe(d.renderTimestamps),f=l>4||d.renderCount>20;r.push({componentName:u,renderCount:d.renderCount,totalDuration:Math.round(d.totalDuration*100)/100,avgDuration:d.renderCount>0?Math.round(d.totalDuration/d.renderCount*100)/100:0,lastRenderPhase:d.lastRenderPhase,lastRenderCause:d.lastRenderCause,renderVelocity:Math.round(l*100)/100,suspicious:f}),f&&c.push(u),i+=d.renderCount}r.sort((u,d)=>d.renderCount-u.renderCount);let o={eventId:m(),sessionId:s,timestamp:Date.now(),eventType:"render",profiles:r,snapshotWindowMs:te,totalRenders:i,suspiciousComponents:c};if(n){let u=n(o);u&&e(u)}else e(o);let a=Date.now();for(let[u,d]of t)a-d.lastRenderTime>xe?t.delete(u):(d.renderCount=0,d.totalDuration=0);if(t.size>ee){let u=[...t.entries()].sort((l,f)=>l[1].lastRenderTime-f[1].lastRenderTime),d=t.size-ee;for(let l=0;l<d;l++)t.delete(u[l][0])}}function re(t,e,s){let n=c=>{let i,o,a;if(c instanceof ErrorEvent)i=c.message||"Uncaught error",o=c.error?.stack,a=c.filename?`${c.filename}:${c.lineno}:${c.colno}`:void 0;else{let d=c.target;if(d&&d!==window){let l=d.tagName?.toLowerCase()??"unknown",f=d.src??d.src??d.href??"unknown";i=`Failed to load resource: <${l}> ${f}`}else return}let u={eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"console",level:"error",message:`[Uncaught] ${i}`,args:[y(i,3)],stackTrace:o,sourceFile:a};if(s){let d=s(u);d&&t(d)}else t(u)},r=c=>{let i=c.reason,o,a;if(i instanceof Error)o=i.message,a=i.stack;else if(typeof i=="string")o=i;else try{o=JSON.stringify(i)}catch{o=String(i)}let u={eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"console",level:"error",message:`[Unhandled Rejection] ${o}`,args:[y(i,3)],stackTrace:a,sourceFile:void 0};if(s){let d=s(u);d&&t(d)}else t(u)};return window.addEventListener("error",n,!0),window.addEventListener("unhandledrejection",r),()=>{window.removeEventListener("error",n,!0),window.removeEventListener("unhandledrejection",r)}}function se(t,e){let s=window.location.href;function n(a,u){let d=s;d!==a&&(s=a,t({eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"navigation",from:d,to:a,trigger:u}))}let r=history.pushState.bind(history),c=history.replaceState.bind(history);history.pushState=function(...a){r(...a),n(window.location.href,"pushState")},history.replaceState=function(...a){c(...a),n(window.location.href,"replaceState")};let i=()=>n(window.location.href,"popstate");window.addEventListener("popstate",i);let o=()=>n(window.location.href,"hashchange");return window.addEventListener("hashchange",o),()=>{history.pushState=r,history.replaceState=c,window.removeEventListener("popstate",i),window.removeEventListener("hashchange",o)}}function oe(t,e){let s=n=>{let r=n.target;if(!(r instanceof Element)||r.closest("[data-runtimescope]"))return;let c=qe(r),i=ze(r),o={eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"ui",action:"click",target:c,...i&&{text:i}};t(o)};return document.addEventListener("click",s,!0),()=>{document.removeEventListener("click",s,!0)}}function qe(t){let e=t.tagName.toLowerCase();if(t.id)return`${e}#${t.id}`;let s=t.getAttribute("data-testid")??t.getAttribute("data-test-id");if(s)return`${e}[data-testid="${s}"]`;let n=t.getAttribute("role"),r=t.getAttribute("aria-label");if(n&&r)return`${e}[role="${n}"][aria-label="${r}"]`;let c=t.className;if(typeof c=="string"&&c.trim()){let o=c.split(/\s+/).find(a=>a.length>2&&!a.startsWith("_")&&!a.includes("__"));if(o)return`${e}.${o}`}let i=t.parentElement;if(i){let o=i.children,a=Array.from(o).filter(u=>u.tagName===t.tagName);if(a.length>1){let u=a.indexOf(t)+1;return`${e}:nth-child(${u})`}}return e}function ze(t){let e=t.getAttribute("aria-label");if(e)return e.slice(0,80);let s=t.innerText??t.textContent;if(!s)return;let n=s.trim().replace(/\s+/g," ");if(n.length!==0)return n.length>80?n.slice(0,77)+"...":n}var q="0.9.1",D=console.debug.bind(console),z=Symbol.for("__runtimescope_originals__");function je(){let t=globalThis;return t[z]||(t[z]={fetch:window.fetch,xhrOpen:XMLHttpRequest.prototype.open,xhrSend:XMLHttpRequest.prototype.send,xhrSetRequestHeader:XMLHttpRequest.prototype.setRequestHeader,consoleMethods:{log:console.log.bind(console),warn:console.warn.bind(console),error:console.error.bind(console),info:console.info.bind(console),debug:console.debug.bind(console),trace:console.trace.bind(console)}}),t[z]}var E=class{static get sessionId(){return this._sessionId}static get isConnected(){return this._state==="started"}static shouldSample(){if(this._sampleRate<1&&Math.random()>this._sampleRate)return!1;if(this._maxEventsPerSecond!==void 0){let e=Date.now();if(e-this._windowStart>=1e3&&(this._windowCount=0,this._windowStart=e),this._windowCount>=this._maxEventsPerSecond)return!1;this._windowCount++}return!0}static connect(e={}){if(e.enabled===!1)return;if(!!!(e.serverUrl||e.endpoint)&&typeof window<"u"){let o=window.location?.hostname;if(o&&o!=="localhost"&&o!=="127.0.0.1"&&!o.startsWith("192.168.")&&!o.startsWith("10.")){D("[RuntimeScope] No endpoint configured and not on localhost \u2014 SDK disabled for production");return}}this._state==="started"&&(D("[RuntimeScope] Already connected \u2014 disconnecting before re-init"),this.disconnect());let n={serverUrl:e.serverUrl??e.endpoint??"ws://localhost:9090",appName:e.appName??"unknown",captureNetwork:e.captureNetwork??!0,captureConsole:e.captureConsole??!0,captureXhr:e.captureXhr??!0,captureBody:e.captureBody??!1,maxBodySize:e.maxBodySize??65536,capturePerformance:e.capturePerformance??!0,captureRenders:e.captureRenders??!0,captureNavigation:e.captureNavigation??!0,captureClicks:e.captureClicks??!0,stores:e.stores??{},beforeSend:e.beforeSend,redactHeaders:e.redactHeaders??["authorization","cookie"],batchSize:e.batchSize??50,flushIntervalMs:e.flushIntervalMs??100};je(),this._sessionId=$(),this._state="started",this.transport=new F({serverUrl:n.serverUrl,appName:n.appName,sessionId:this._sessionId,sdkVersion:q,authToken:e.authToken,projectId:e.projectId,batchSize:n.batchSize,flushIntervalMs:n.flushIntervalMs}),this._sampleRate=e.sampleRate??1,this._maxEventsPerSecond=e.maxEventsPerSecond,this._windowCount=0,this._windowStart=Date.now(),this._user=e.user,this.transport.connect(),D(`[RuntimeScope] SDK v${q} initializing \u2014 app: ${n.appName}, server: ${n.serverUrl}`);let r=o=>{o.eventType!=="session"&&o.eventType!=="custom"&&o.eventType!=="ui"&&!this.shouldSample()||this.transport?.send(o)};r({eventId:m(),sessionId:this._sessionId,timestamp:Date.now(),eventType:"session",appName:n.appName,connectedAt:Date.now(),sdkVersion:q,buildMeta:e.buildMeta,user:this._user,projectId:e.projectId});let c=this._sessionId;this.transport.onCommand(o=>{this.handleCommand(o,r,c)}),n.captureNetwork&&this.restoreFns.push(W(r,this._sessionId,n.redactHeaders,{captureBody:n.captureBody,maxBodySize:n.maxBodySize,beforeSend:n.beforeSend})),n.captureXhr&&this.restoreFns.push(Q(r,this._sessionId,n.redactHeaders,{captureBody:n.captureBody,maxBodySize:n.maxBodySize,beforeSend:n.beforeSend})),n.captureConsole&&(this.restoreFns.push(G(r,this._sessionId,n.beforeSend)),this.restoreFns.push(re(r,this._sessionId,n.beforeSend))),Object.keys(n.stores).length>0&&this.restoreFns.push(Y(r,this._sessionId,n.stores,{beforeSend:n.beforeSend})),n.capturePerformance&&this.restoreFns.push(J(r,this._sessionId,{beforeSend:n.beforeSend})),n.captureRenders&&this.restoreFns.push(ne(r,this._sessionId,{beforeSend:n.beforeSend})),n.captureNavigation&&this.restoreFns.push(se(r,this._sessionId)),n.captureClicks&&this.restoreFns.push(oe(r,this._sessionId));let i=[n.captureNetwork&&"fetch",n.captureXhr&&"xhr",n.captureConsole&&"console, errors",Object.keys(n.stores).length>0&&"state",n.capturePerformance&&"performance",n.captureRenders&&"renders",n.captureNavigation&&"navigation",n.captureClicks&&"clicks"].filter(Boolean);D(`[RuntimeScope] Interceptors active \u2014 ${i.join(", ")}`),this._sampleRate<1&&D(`[RuntimeScope] Sampling at ${(this._sampleRate*100).toFixed(0)}%`),this._maxEventsPerSecond!==void 0&&D(`[RuntimeScope] Rate limited to ${this._maxEventsPerSecond} events/sec`)}static handleCommand(e,s,n){if(e.command==="capture_dom_snapshot"){let r=e.params?.maxSize??5e5,c=document.documentElement.outerHTML,i=c.length>r;i&&(c=c.slice(0,r));let o={eventId:m(),sessionId:n,timestamp:Date.now(),eventType:"dom_snapshot",html:c,url:window.location.href,viewport:{width:window.innerWidth,height:window.innerHeight},scrollPosition:{x:window.scrollX,y:window.scrollY},elementCount:document.querySelectorAll("*").length,truncated:i};s(o),this.transport?.sendCommandResponse(e.requestId,e.command,o)}else this.transport?.sendCommandResponse(e.requestId,e.command,{error:"Unknown command"})}static init(e={}){return this.connect(e)}static track(e,s){if(!this.transport||!this._sessionId)return;let n={eventId:m(),sessionId:this._sessionId,timestamp:Date.now(),eventType:"custom",name:e,properties:s};this.transport.send(n)}static setUser(e){this._user=e??void 0,this.transport&&this._sessionId&&this.transport.send({eventId:m(),sessionId:this._sessionId,timestamp:Date.now(),eventType:"session",appName:"user_update",connectedAt:Date.now(),sdkVersion:q,user:this._user})}static addBreadcrumb(e,s){if(!this.transport||!this._sessionId)return;let n={eventId:m(),sessionId:this._sessionId,timestamp:Date.now(),eventType:"ui",action:"breadcrumb",target:"manual",text:e,...s&&{data:s}};this.transport.send(n)}static disconnect(){for(let s of this.restoreFns)try{s()}catch{}this.restoreFns=[];let e=globalThis[z];if(e){window.fetch!==e.fetch&&(window.fetch=e.fetch);for(let[s,n]of Object.entries(e.consoleMethods)){let r=console;r[s]!==n&&(r[s]=n)}}this.transport?.disconnect(),this.transport=null,this._sessionId=null,this._state="stopped"}};p(E,"transport",null),p(E,"restoreFns",[]),p(E,"_sessionId",null),p(E,"_state","stopped"),p(E,"_sampleRate",1),p(E,"_maxEventsPerSecond"),p(E,"_windowCount",0),p(E,"_windowStart",0),p(E,"_user");var Ue=E;return pe(Xe);})();
|
|
4
|
+
`):void 0,sourceFile:Q(g),source:"browser"};if(r){let T=r(E);T&&t(T)}else t(E);s[d](...h)};let a=console.assert?.bind(console);a&&(console.assert=(d,...h)=>{if(!d){let g=new Error().stack,_=`Assertion failed: ${h.map(E=>typeof E=="string"?E:K(E)).join(" ")}`;t({eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"console",level:"error",message:_,args:h.map(E=>y(E,3)),stackTrace:g?.split(`
|
|
5
|
+
`).slice(2).join(`
|
|
6
|
+
`),sourceFile:Q(g),source:"browser"})}a(d,...h)});let i=console.time?.bind(console),o=console.timeEnd?.bind(console);i&&(console.time=(d="default")=>{n.set(d,performance.now()),i(d)}),o&&(console.timeEnd=(d="default")=>{let h=n.get(d);if(h!==void 0){let g=performance.now()-h;n.delete(d),t({eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"console",level:"info",message:`${d}: ${g.toFixed(2)}ms`,args:[{label:d,duration:g}],source:"browser"})}o(d)});let u=console.count?.bind(console),p=console.countReset?.bind(console);u&&(console.count=(d="default")=>{let h=(c.get(d)??0)+1;c.set(d,h),t({eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"console",level:"info",message:`${d}: ${h}`,args:[{label:d,count:h}],source:"browser"}),u(d)}),p&&(console.countReset=(d="default")=>{c.delete(d),p(d)});let l=console.table?.bind(console);return l&&(console.table=(d,h)=>{t({eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"console",level:"info",message:`[table] ${Array.isArray(d)?`${d.length} rows`:typeof d}`,args:[y(d,3)],source:"browser"}),l(d,h)}),()=>{for(let d of G)console[d]=s[d];a&&(console.assert=a),i&&(console.time=i),o&&(console.timeEnd=o),u&&(console.count=u),p&&(console.countReset=p),l&&(console.table=l)}}function K(t){try{return JSON.stringify(t)}catch{return String(t)}}function J(t,e,r,s){let n=new Set(r.map(l=>l.toLowerCase())),c=s?.captureBody??!1,a=s?.maxBodySize??65536,i=new AbortController,o=XMLHttpRequest.prototype.open,u=XMLHttpRequest.prototype.setRequestHeader,p=XMLHttpRequest.prototype.send;return XMLHttpRequest.prototype.open=function(l,d){return this.__rs_method=l.toUpperCase(),this.__rs_url=typeof d=="string"?d:d.href,this.__rs_headers={},o.apply(this,arguments)},XMLHttpRequest.prototype.setRequestHeader=function(l,d){return this.__rs_headers&&(this.__rs_headers[l.toLowerCase()]=n.has(l.toLowerCase())?"[REDACTED]":d),u.call(this,l,d)},XMLHttpRequest.prototype.send=function(l){let d=this.__rs_method??"GET",h=this.__rs_url??"",g=`${d}:${h}`,_=!1;for(let w of L.keys())if(w.startsWith(g)){_=!0;break}if(_)return this.__rs_fetchIntercepted=!0,p.call(this,l);let E={...this.__rs_headers??{}},T=performance.now(),v,k=0;if(l){if(typeof l=="string")k=new Blob([l]).size,c&&(v=l.length>a?l.slice(0,a):l);else if(l instanceof Blob)k=l.size,c&&(v=`[Blob ${l.size} bytes]`);else if(l instanceof ArrayBuffer)k=l.byteLength,c&&(v=`[ArrayBuffer ${l.byteLength} bytes]`);else if(l instanceof FormData)c&&(v="[FormData]");else if(l instanceof URLSearchParams){let w=l.toString();k=new Blob([w]).size,c&&(v=w.length>a?w.slice(0,a):w)}}let x=Le(l),C=w=>{let R={eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"network",url:h,method:d,status:0,requestHeaders:E,responseHeaders:{},requestBodySize:k,responseBodySize:0,duration:0,ttfb:0,graphqlOperation:x,requestBody:v,source:"xhr",...w};if(s?.beforeSend){let I=s.beforeSend(R);I&&t(I)}else t(R)};return this.addEventListener("loadend",()=>{let w=performance.now()-T;if(this.status>0){let R=Ce(this.getAllResponseHeaders(),n),I=parseInt(this.getResponseHeader("content-length")||"0",10),O;if(c&&(this.responseType===""||this.responseType==="text"))try{let U=this.responseText;O=U.length>a?U.slice(0,a):U}catch{}C({status:this.status,responseHeaders:R,responseBodySize:I,responseBody:O,duration:w,ttfb:w})}else{let R="error",I="Network error";this.readyState===0||this.status,this.timeout>0&&w>=this.timeout&&(R="timeout",I=`Request timed out after ${this.timeout}ms`),C({duration:w,errorPhase:R,errorMessage:I})}},{once:!0,signal:i.signal}),p.call(this,l)},()=>{i.abort(),XMLHttpRequest.prototype.open=o,XMLHttpRequest.prototype.setRequestHeader=u,XMLHttpRequest.prototype.send=p}}function Ce(t,e){let r={};if(!t)return r;for(let s of t.trim().split(/[\r\n]+/)){let n=s.indexOf(":");if(n===-1)continue;let c=s.slice(0,n).trim().toLowerCase(),a=s.slice(n+1).trim();r[c]=e.has(c)?"[REDACTED]":a}return r}function Le(t){if(!(!t||typeof t!="string"))try{let e=JSON.parse(t);if(typeof e.query=="string"){let r=e.query.trim(),s="query";r.startsWith("mutation")?s="mutation":r.startsWith("subscription")&&(s="subscription");let n=e.operationName||De(r)||"anonymous";return{type:s,name:n}}}catch{}}function De(t){return t.match(/^(?:query|mutation|subscription)\s+(\w+)/)?.[1]}function ee(t,e,r,s){let n=[],c=new Map;for(let[a,i]of Object.entries(r)){let o=Ne(i);if(o==="zustand"){let u=i;j(t,e,s?.beforeSend,{storeId:a,library:o,phase:"init",state:y(u.getState(),4)});let p=u.subscribe((l,d)=>{let h=Z(d,l);j(t,e,s?.beforeSend,{storeId:a,library:o,phase:"update",state:y(l,4),previousState:y(d,4),diff:h?y(h,3):void 0})});n.push(p)}else if(o==="redux"){let u=i;j(t,e,s?.beforeSend,{storeId:a,library:o,phase:"init",state:y(u.getState(),4)});let p,l=u.dispatch.bind(u);c.set(a,l),u.dispatch=g=>(g&&typeof g=="object"&&"type"in g&&(p={type:String(g.type),payload:g.payload}),l(g));let d=u.getState(),h=u.subscribe(()=>{let g=u.getState(),_=Z(d,g);j(t,e,s?.beforeSend,{storeId:a,library:o,phase:"update",state:y(g,4),previousState:y(d,4),diff:_?y(_,3):void 0,action:p?y(p,3):void 0}),d=g,p=void 0});n.push(h)}}return()=>{for(let a of n)a();for(let[a,i]of c){let o=r[a];o&&(o.dispatch=i)}}}function Ne(t){if(!t||typeof t!="object")return"unknown";let e=t;return typeof e.getState=="function"&&typeof e.setState=="function"&&typeof e.subscribe=="function"?"zustand":typeof e.dispatch=="function"&&typeof e.getState=="function"&&typeof e.subscribe=="function"?"redux":"unknown"}function Z(t,e){if(!t||!e||typeof t!="object"||typeof e!="object")return null;let r={},s=t,n=e,c=new Set([...Object.keys(s),...Object.keys(n)]);for(let a of c)s[a]!==n[a]&&(r[a]={from:s[a],to:n[a]});return Object.keys(r).length>0?r:null}function j(t,e,r,s){let n={eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"state",...s};if(r){let c=r(n);c&&t(c)}else t(n)}var xe={LCP:[2500,4e3],FCP:[1800,3e3],CLS:[.1,.25],TTFB:[800,1800],FID:[100,300],INP:[200,500]};function Oe(t,e){let[r,s]=xe[t]??[1/0,1/0];return e<=r?"good":e<=s?"needs-improvement":"poor"}var F=null;function te(t,e,r){if(F)for(let i of F)try{i.disconnect()}catch{}let s=[];F=s;let n=(i,o,u)=>{let p={eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"performance",metricName:i,value:Math.round(o*100)/100,rating:Oe(i,o),element:u};if(r?.beforeSend){let l=r.beforeSend(p);l&&t(l)}else t(p)};A(s,"largest-contentful-paint",i=>{let o=i[i.length-1];if(!o)return;let u=o.element;n("LCP",o.startTime,u?.tagName?.toLowerCase())}),A(s,"paint",i=>{for(let o of i)o.name==="first-contentful-paint"&&n("FCP",o.startTime)});let c=0;A(s,"layout-shift",i=>{for(let o of i){let u=o;!u.hadRecentInput&&u.value&&(c+=u.value,n("CLS",c))}}),A(s,"first-input",i=>{let o=i[0];if(!o)return;let u=o;u.processingStart&&n("FID",u.processingStart-o.startTime)}),A(s,"navigation",i=>{let o=i[0];o&&n("TTFB",o.responseStart-o.requestStart)});let a=0;return A(s,"event",i=>{for(let o of i)o.duration>a&&(a=o.duration,n("INP",a))},{durationThreshold:16}),()=>{for(let i of s)try{i.disconnect()}catch{}F===s&&(F=null)}}function A(t,e,r,s){try{let n=new PerformanceObserver(c=>{r(c.getEntries())});n.observe({type:e,buffered:!0,...s}),t.push(n)}catch{}}var Ae=0,He=1,se=1e4,ne=100,Fe=6e4,re=500;function oe(t,e,r){let s=new Map,n=r?.snapshotIntervalMs??5e3,c=null,a=Me();if(!a)return()=>{};let i=a.onCommitFiberRoot;return a._runtimescope_original=i,a.onCommitFiberRoot=(o,u)=>{if(i)try{i(o,u)}catch{}u.current&&X(u.current,s)},c=setInterval(()=>{qe(s,t,e,r?.beforeSend)},n),()=>{c&&(clearInterval(c),c=null),a&&(a._runtimescope_original?a.onCommitFiberRoot=a._runtimescope_original:delete a.onCommitFiberRoot,delete a._runtimescope_original)}}function Me(){if(typeof window>"u")return null;let t=window;return t.__REACT_DEVTOOLS_GLOBAL_HOOK__||(t.__REACT_DEVTOOLS_GLOBAL_HOOK__={}),t.__REACT_DEVTOOLS_GLOBAL_HOOK__}function X(t,e){Pe(t,e),t.child&&X(t.child,e),t.sibling&&X(t.sibling,e)}function Pe(t,e){if(t.tag!==Ae&&t.tag!==He)return;let r=Be(t);if(!r)return;let s=Date.now(),n=t.alternate===null,c=t.actualDuration??0,a=je(t,n),i=e.get(r);i||(i={renderCount:0,totalDuration:0,lastRenderTime:0,lastRenderPhase:"mount",lastRenderCause:"unknown",renderTimestamps:[]},e.set(r,i)),i.renderCount++,i.totalDuration+=c,i.lastRenderTime=s,i.lastRenderPhase=n?"mount":"update",i.lastRenderCause=a??"unknown",i.renderTimestamps.push(s),i.renderTimestamps.length>ne&&(i.renderTimestamps=i.renderTimestamps.slice(-ne))}function Be(t){if(t.type&&typeof t.type!="string")return t.type.displayName||t.type.name||void 0}function je(t,e){return e?"props":t.alternate?t.memoizedProps!==t.alternate.memoizedProps?"props":t.memoizedState!==t.alternate.memoizedState?"state":"parent":"unknown"}function $e(t){if(t.length<2)return 0;let e=Date.now(),r=e-se,s=t.filter(c=>c>=r);if(s.length<2)return 0;let n=e-s[0];return n===0?0:s.length/(n/1e3)}function qe(t,e,r,s){if(t.size===0)return;let n=[],c=[],a=0;for(let[u,p]of t){let l=$e(p.renderTimestamps),d=l>4||p.renderCount>20;n.push({componentName:u,renderCount:p.renderCount,totalDuration:Math.round(p.totalDuration*100)/100,avgDuration:p.renderCount>0?Math.round(p.totalDuration/p.renderCount*100)/100:0,lastRenderPhase:p.lastRenderPhase,lastRenderCause:p.lastRenderCause,renderVelocity:Math.round(l*100)/100,suspicious:d}),d&&c.push(u),a+=p.renderCount}n.sort((u,p)=>p.renderCount-u.renderCount);let i={eventId:m(),sessionId:r,timestamp:Date.now(),eventType:"render",profiles:n,snapshotWindowMs:se,totalRenders:a,suspiciousComponents:c};if(s){let u=s(i);u&&e(u)}else e(i);let o=Date.now();for(let[u,p]of t)o-p.lastRenderTime>Fe?t.delete(u):(p.renderCount=0,p.totalDuration=0);if(t.size>re){let u=[...t.entries()].sort((l,d)=>l[1].lastRenderTime-d[1].lastRenderTime),p=t.size-re;for(let l=0;l<p;l++)t.delete(u[l][0])}}function ie(t,e,r){let s=c=>{let a,i,o;if(c instanceof ErrorEvent)a=c.message||"Uncaught error",i=c.error?.stack,o=c.filename?`${c.filename}:${c.lineno}:${c.colno}`:void 0;else{let p=c.target;if(p&&p!==window){let l=p.tagName?.toLowerCase()??"unknown",d=p.src??p.src??p.href??"unknown";a=`Failed to load resource: <${l}> ${d}`}else return}let u={eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"console",level:"error",message:`[Uncaught] ${a}`,args:[y(a,3)],stackTrace:i,sourceFile:o};if(r){let p=r(u);p&&t(p)}else t(u)},n=c=>{let a=c.reason,i,o;if(a instanceof Error)i=a.message,o=a.stack;else if(typeof a=="string")i=a;else try{i=JSON.stringify(a)}catch{i=String(a)}let u={eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"console",level:"error",message:`[Unhandled Rejection] ${i}`,args:[y(a,3)],stackTrace:o,sourceFile:void 0};if(r){let p=r(u);p&&t(p)}else t(u)};return window.addEventListener("error",s,!0),window.addEventListener("unhandledrejection",n),()=>{window.removeEventListener("error",s,!0),window.removeEventListener("unhandledrejection",n)}}function ae(t,e){let r=window.location.href;function s(o,u){let p=r;p!==o&&(r=o,t({eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"navigation",from:p,to:o,trigger:u}))}let n=history.pushState.bind(history),c=history.replaceState.bind(history);history.pushState=function(...o){n(...o),s(window.location.href,"pushState")},history.replaceState=function(...o){c(...o),s(window.location.href,"replaceState")};let a=()=>s(window.location.href,"popstate");window.addEventListener("popstate",a);let i=()=>s(window.location.href,"hashchange");return window.addEventListener("hashchange",i),()=>{history.pushState=n,history.replaceState=c,window.removeEventListener("popstate",a),window.removeEventListener("hashchange",i)}}function ce(t,e){let r=s=>{let n=s.target;if(!(n instanceof Element)||n.closest("[data-runtimescope]"))return;let c=ze(n),a=Ue(n),i={eventId:m(),sessionId:e,timestamp:Date.now(),eventType:"ui",action:"click",target:c,...a&&{text:a}};t(i)};return document.addEventListener("click",r,!0),()=>{document.removeEventListener("click",r,!0)}}function ze(t){let e=t.tagName.toLowerCase();if(t.id)return`${e}#${t.id}`;let r=t.getAttribute("data-testid")??t.getAttribute("data-test-id");if(r)return`${e}[data-testid="${r}"]`;let s=t.getAttribute("role"),n=t.getAttribute("aria-label");if(s&&n)return`${e}[role="${s}"][aria-label="${n}"]`;let c=t.className;if(typeof c=="string"&&c.trim()){let i=c.split(/\s+/).find(o=>o.length>2&&!o.startsWith("_")&&!o.includes("__"));if(i)return`${e}.${i}`}let a=t.parentElement;if(a){let i=a.children,o=Array.from(i).filter(u=>u.tagName===t.tagName);if(o.length>1){let u=o.indexOf(t)+1;return`${e}:nth-child(${u})`}}return e}function Ue(t){let e=t.getAttribute("aria-label");if(e)return e.slice(0,80);let r=t.innerText??t.textContent;if(!r)return;let s=r.trim().replace(/\s+/g," ");if(s.length!==0)return s.length>80?s.slice(0,77)+"...":s}function $(t){let e=t.startsWith("runtimescopes://");if(!t.startsWith("runtimescope://")&&!e)throw new Error("Invalid RuntimeScope DSN: must start with runtimescope:// or runtimescopes://");let r=new URL(t.replace(/^runtimescopes?:\/\//,"http://")),s=r.username;if(!s||!s.startsWith("proj_"))throw new Error("Invalid RuntimeScope DSN: missing projectId (expected proj_xxx@host)");let n=r.hostname,c=r.port?parseInt(r.port):9091,a=c-1,i=r.pathname.replace(/^\//,"")||void 0,o=e?"wss":"ws",u=e?"https":"http";return{projectId:s,wsEndpoint:`${o}://${n}:${a}`,httpEndpoint:`${u}://${n}:${c}`,appName:i,tls:e}}function ue(t){let e=t.tls?"runtimescopes":"runtimescope",r=t.host??"localhost",s=t.port??9091,n=t.appName?`/${t.appName}`:"";return`${e}://${t.projectId}@${r}:${s}${n}`}var q="0.9.3",N=console.debug.bind(console),z=Symbol.for("__runtimescope_originals__");function Xe(){let t=globalThis;return t[z]||(t[z]={fetch:window.fetch,xhrOpen:XMLHttpRequest.prototype.open,xhrSend:XMLHttpRequest.prototype.send,xhrSetRequestHeader:XMLHttpRequest.prototype.setRequestHeader,consoleMethods:{log:console.log.bind(console),warn:console.warn.bind(console),error:console.error.bind(console),info:console.info.bind(console),debug:console.debug.bind(console),trace:console.trace.bind(console)}}),t[z]}var b=class{static get sessionId(){return this._sessionId}static get isConnected(){return this._state==="started"}static shouldSample(){if(this._sampleRate<1&&Math.random()>this._sampleRate)return!1;if(this._maxEventsPerSecond!==void 0){let e=Date.now();if(e-this._windowStart>=1e3&&(this._windowCount=0,this._windowStart=e),this._windowCount>=this._maxEventsPerSecond)return!1;this._windowCount++}return!0}static connect(e={}){if(e.enabled===!1)return;let r=!1;if(e.dsn)try{let o=$(e.dsn);e={...e,serverUrl:o.wsEndpoint,projectId:o.projectId,...o.appName&&!e.appName?{appName:o.appName}:{}},r=!0}catch(o){N("[RuntimeScope] Invalid DSN:",o.message)}if(!(!!(e.serverUrl||e.endpoint)||r)&&typeof window<"u"){let o=window.location?.hostname;if(o&&o!=="localhost"&&o!=="127.0.0.1"&&!o.startsWith("192.168.")&&!o.startsWith("10.")){N("[RuntimeScope] No endpoint configured and not on localhost \u2014 SDK disabled for production");return}}this._state==="started"&&(N("[RuntimeScope] Already connected \u2014 disconnecting before re-init"),this.disconnect());let n={serverUrl:e.serverUrl??e.endpoint??"ws://localhost:9090",appName:e.appName??"unknown",captureNetwork:e.captureNetwork??!0,captureConsole:e.captureConsole??!0,captureXhr:e.captureXhr??!0,captureBody:e.captureBody??!1,maxBodySize:e.maxBodySize??65536,capturePerformance:e.capturePerformance??!0,captureRenders:e.captureRenders??!0,captureNavigation:e.captureNavigation??!0,captureClicks:e.captureClicks??!0,stores:e.stores??{},beforeSend:e.beforeSend,redactHeaders:e.redactHeaders??["authorization","cookie"],batchSize:e.batchSize??50,flushIntervalMs:e.flushIntervalMs??100};Xe(),this._sessionId=W(),this._state="started",this.transport=new P({serverUrl:n.serverUrl,appName:n.appName,sessionId:this._sessionId,sdkVersion:q,authToken:e.authToken,projectId:e.projectId,batchSize:n.batchSize,flushIntervalMs:n.flushIntervalMs}),this._sampleRate=e.sampleRate??1,this._maxEventsPerSecond=e.maxEventsPerSecond,this._windowCount=0,this._windowStart=Date.now(),this._user=e.user,this.transport.connect(),N(`[RuntimeScope] SDK v${q} initializing \u2014 app: ${n.appName}, server: ${n.serverUrl}`);let c=o=>{o.eventType!=="session"&&o.eventType!=="custom"&&o.eventType!=="ui"&&!this.shouldSample()||this.transport?.send(o)};c({eventId:m(),sessionId:this._sessionId,timestamp:Date.now(),eventType:"session",appName:n.appName,connectedAt:Date.now(),sdkVersion:q,buildMeta:e.buildMeta,user:this._user,projectId:e.projectId});let a=this._sessionId;this.transport.onCommand(o=>{this.handleCommand(o,c,a)}),n.captureNetwork&&this.restoreFns.push(V(c,this._sessionId,n.redactHeaders,{captureBody:n.captureBody,maxBodySize:n.maxBodySize,beforeSend:n.beforeSend})),n.captureXhr&&this.restoreFns.push(J(c,this._sessionId,n.redactHeaders,{captureBody:n.captureBody,maxBodySize:n.maxBodySize,beforeSend:n.beforeSend})),n.captureConsole&&this.restoreFns.push(Y(c,this._sessionId,n.beforeSend)),e.captureErrors!==!1&&this.restoreFns.push(ie(c,this._sessionId,n.beforeSend)),Object.keys(n.stores).length>0&&this.restoreFns.push(ee(c,this._sessionId,n.stores,{beforeSend:n.beforeSend})),n.capturePerformance&&this.restoreFns.push(te(c,this._sessionId,{beforeSend:n.beforeSend})),n.captureRenders&&this.restoreFns.push(oe(c,this._sessionId,{beforeSend:n.beforeSend})),n.captureNavigation&&this.restoreFns.push(ae(c,this._sessionId)),n.captureClicks&&this.restoreFns.push(ce(c,this._sessionId));let i=[n.captureNetwork&&"fetch",n.captureXhr&&"xhr",n.captureConsole&&"console, errors",Object.keys(n.stores).length>0&&"state",n.capturePerformance&&"performance",n.captureRenders&&"renders",n.captureNavigation&&"navigation",n.captureClicks&&"clicks"].filter(Boolean);N(`[RuntimeScope] Interceptors active \u2014 ${i.join(", ")}`),this._sampleRate<1&&N(`[RuntimeScope] Sampling at ${(this._sampleRate*100).toFixed(0)}%`),this._maxEventsPerSecond!==void 0&&N(`[RuntimeScope] Rate limited to ${this._maxEventsPerSecond} events/sec`)}static handleCommand(e,r,s){if(e.command==="capture_dom_snapshot"){let n=e.params?.maxSize??5e5,c=document.documentElement.outerHTML,a=c.length>n;a&&(c=c.slice(0,n));let i={eventId:m(),sessionId:s,timestamp:Date.now(),eventType:"dom_snapshot",html:c,url:window.location.href,viewport:{width:window.innerWidth,height:window.innerHeight},scrollPosition:{x:window.scrollX,y:window.scrollY},elementCount:document.querySelectorAll("*").length,truncated:a};r(i),this.transport?.sendCommandResponse(e.requestId,e.command,i)}else this.transport?.sendCommandResponse(e.requestId,e.command,{error:"Unknown command"})}static init(e={}){return this.connect(e)}static track(e,r){if(!this.transport||!this._sessionId)return;let s={eventId:m(),sessionId:this._sessionId,timestamp:Date.now(),eventType:"custom",name:e,properties:r};this.transport.send(s)}static setUser(e){this._user=e??void 0,this.transport&&this._sessionId&&this.transport.send({eventId:m(),sessionId:this._sessionId,timestamp:Date.now(),eventType:"session",appName:"user_update",connectedAt:Date.now(),sdkVersion:q,user:this._user})}static addBreadcrumb(e,r){if(!this.transport||!this._sessionId)return;let s={eventId:m(),sessionId:this._sessionId,timestamp:Date.now(),eventType:"ui",action:"breadcrumb",target:"manual",text:e,...r&&{data:r}};this.transport.send(s)}static disconnect(){for(let r of this.restoreFns)try{r()}catch{}this.restoreFns=[];let e=globalThis[z];if(e){window.fetch!==e.fetch&&(window.fetch=e.fetch);for(let[r,s]of Object.entries(e.consoleMethods)){let n=console;n[r]!==s&&(n[r]=s)}}this.transport?.disconnect(),this.transport=null,this._sessionId=null,this._state="stopped"}};f(b,"transport",null),f(b,"restoreFns",[]),f(b,"_sessionId",null),f(b,"_state","stopped"),f(b,"_sampleRate",1),f(b,"_maxEventsPerSecond"),f(b,"_windowCount",0),f(b,"_windowStart",0),f(b,"_user");var We=b;return ge(Ve);})();
|
|
4
7
|
if(typeof RuntimeScope!=="undefined"&&RuntimeScope.RuntimeScope){RuntimeScope=RuntimeScope.RuntimeScope;}
|
|
5
8
|
//# sourceMappingURL=index.global.js.map
|