@aj-2000-test/goodlogs-sdk 0.1.20 → 0.3.0
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/bin/goodlogs.cjs +180 -0
- package/dist/client-w3t1Yzjd.d.cts +231 -0
- package/dist/client-w3t1Yzjd.d.ts +231 -0
- package/dist/index.cjs +6 -3
- package/dist/index.d.cts +431 -93
- package/dist/index.d.ts +431 -93
- package/dist/index.js +6 -3
- package/dist/replay.cjs +2 -0
- package/dist/replay.d.cts +70 -0
- package/dist/replay.d.ts +70 -0
- package/dist/replay.js +2 -0
- package/package.json +13 -3
package/dist/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
var
|
|
2
|
-
`);if(!
|
|
1
|
+
var S=(o=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(o,{get:(t,e)=>(typeof require<"u"?require:t)[e]}):o)(function(o){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+o+'" is not supported')});var I={us:"https://goodlogs-api-us.happyhill-a7c56143.centralindia.azurecontainerapps.io",eu:"https://goodlogs-api-eu.yellowmeadow-422296f6.japaneast.azurecontainerapps.io",ap:"https://goodlogs-api-ap.delightfulsand-90b72c09.southeastasia.azurecontainerapps.io"};function B(o){let t=o.split("_");return t.length>=4&&t[0]==="gl"?t[2]:"eu"}function y(o,t){if(t)return t;let e=B(o);return I[e]||I.eu}var G=5e3,F=50,v="0.3.0",w="gl_anon_id",_="gl_session_id";function b(){return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,o=>{let t=Math.random()*16|0;return (o==="x"?t:t&3|8).toString(16)})}function M(){let o={$goodlogs_sdk:"js",$goodlogs_sdk_version:v};return typeof navigator>"u"||(typeof screen<"u"&&(o.$screen=`${screen.width}x${screen.height}`),typeof navigator<"u"&&(o.$language=navigator.language??""),typeof location<"u"&&(o.$url=location.href,o.$path=location.pathname,o.$page=location.pathname.split("/").filter(Boolean).pop()||"/"),typeof document<"u"&&(document.referrer&&(o.$referrer=document.referrer),document.title&&(o.$title=document.title))),o}function U(o,t){let e={$session_id:o,$distinct_id:t,$goodlogs_sdk:"js",$goodlogs_sdk_version:v};return typeof navigator>"u"||typeof location<"u"&&(e.$url=location.href,e.$path=location.pathname),e}function D(){if(!(typeof document<"u"))try{let t=new Error().stack?.split(`
|
|
2
|
+
`);if(!t)return;for(let e=3;e<Math.min(t.length,8);e++){let n=t[e]?.trim();if(!n||n.includes("goodlogs")&&(n.includes("client.")||n.includes("index.")))continue;let r=n.match(/at\s+(?:(.+?)\s+\()?(.+?):(\d+):\d+\)?/);if(r){let s=r[1]||"<anonymous>",i=r[2]?.replace(/^.*[/\\]/,"")??"",d=r[3];return `${s}@${i}:${d}`}}}catch{}}function K(){if(typeof localStorage<"u"){let o=localStorage.getItem(w);if(o)return o;let t=b();return localStorage.setItem(w,t),t}return b()}function X(){if(typeof sessionStorage<"u"){let o=sessionStorage.getItem(_);if(o)return o;let t=b();return sessionStorage.setItem(_,t),t}return b()}function z(){let o="";for(let t=0;t<32;t++)o+=(Math.random()*16|0).toString(16);return o}function V(){let o="";for(let t=0;t<16;t++)o+=(Math.random()*16|0).toString(16);return o}function W(o,t){switch(o){case "lcp":return t<=2500?"good":t<=4e3?"needs-improvement":"poor";case "inp":return t<=200?"good":t<=500?"needs-improvement":"poor";case "cls":return t<=.1?"good":t<=.25?"needs-improvement":"poor";case "fcp":return t<=1800?"good":t<=3e3?"needs-improvement":"poor";case "ttfb":return t<=800?"good":t<=1800?"needs-improvement":"poor";default:return}}function J(o){if(!o)return [];let t=[];for(let e of o.split(`
|
|
3
|
+
`)){let n=e.trim();if(!n||n.startsWith("Error")||n.startsWith("at Error"))continue;let r=/^at\s+(?:(.+?)\s+\()?(.+?):(\d+):(\d+)\)?$/.exec(n);if(r){let s=r[1]?.trim(),i=r[2];t.push({function:s&&s!=="<anonymous>"?s:void 0,filename:i,lineno:Number(r[3]),colno:Number(r[4]),abs_path:i,in_app:!i.includes("node_modules/")&&!i.includes("/dist/")&&!i.startsWith("internal/")});continue}if(r=/^([^@]*)@(.+?):(\d+):(\d+)$/.exec(n),r){let s=r[1]?.trim(),i=r[2];t.push({function:s||void 0,filename:i,lineno:Number(r[3]),colno:Number(r[4]),abs_path:i,in_app:!i.includes("node_modules/")&&!i.includes("/dist/")});}}return t}var R=class R{constructor(t){this.originalFetch=null;this.xhrPatched=false;this.logBuffer=[];this.eventBuffer=[];this.errorBuffer=[];this.vitalBuffer=[];this.spanBuffer=[];this.breadcrumbBuffer=[];this.timer=null;this.visibilityHandler=null;this.clickHandler=null;this.lastPath="";this.navTransaction=null;this.errorHandler=null;this.rejectionHandler=null;this.apiKey=t.apiKey,this.endpoint=y(t.apiKey,t.endpoint).replace(/\/+$/,""),this.flushInterval=t.flushInterval??G,this.batchSize=t.batchSize??F,this.defaultContext=t.defaultContext??{},this.onError=t.onError??(()=>{}),this.disabled=t.disabled??false,this.telemetry=t.telemetry??true,this.useEnvelope=t.useEnvelope??false,this.autoFetch=t.autoFetch??(this.useEnvelope&&t.autocapture!==false),this.anonymousId=K(),this.sessionId=X(),this.disabled&&typeof console<"u"&&console.warn("[GoodLogs] SDK is disabled. No events or logs will be sent."),this.disabled||(this.startTimer(),this.attachPageLifecycle(),t.autocapture!==false&&(this.attachClickCapture(),this.captureWebVitals(),this.attachPageviewCapture(),this.attachGlobalErrorHandlers()),this.autoFetch&&(this.attachFetchInstrumentation(),this.attachXhrInstrumentation()),this.sendTelemetry("init","info"));}log(t,e,n){if(this.disabled)return;let r=65536,s=e;e.length>r&&(s=e.slice(0,r-100)+`
|
|
3
4
|
|
|
4
|
-
[truncated \u2014 original ${
|
|
5
|
+
[truncated \u2014 original ${e.length} chars, limit ${r}]`,this.onError(new Error(`Log message truncated from ${e.length} to ${r} chars`)));let i=D(),d={severity:t,message:s,properties:{...this.defaultContext,...U(this.sessionId,this.anonymousId),...i?{code_location:i}:{},...n},timestamp:new Date().toISOString()};this.logBuffer.push(d),this.logBuffer.length>=this.batchSize&&this.flush();}debug(t,e){this.log("debug",t,e);}info(t,e){this.log("info",t,e);}warn(t,e){this.log("warn",t,e);}error(t,e){this.log("error",t,e);}fatal(t,e){this.log("fatal",t,e);}identify(t){this.anonymousId=t,typeof localStorage<"u"&&localStorage.setItem(w,t);}getDistinctId(){return this.anonymousId}reset(){this.anonymousId=b(),this.sessionId=b(),typeof localStorage<"u"&&localStorage.setItem(w,this.anonymousId),typeof sessionStorage<"u"&&sessionStorage.setItem(_,this.sessionId);}getSessionId(){return this.sessionId}newSession(){this.sessionId=b(),typeof sessionStorage<"u"&&sessionStorage.setItem(_,this.sessionId);}setSessionId(t){this.sessionId=t,typeof sessionStorage<"u"&&sessionStorage.setItem(_,t);}track(t,e){if(this.disabled)return;let{distinctId:n,...r}=e??{},s={event:t,distinctId:n??this.anonymousId,properties:{...M(),...r,$session_id:this.sessionId},timestamp:new Date().toISOString()};this.eventBuffer.push(s),this.eventBuffer.length>=this.batchSize&&this.flush();}addBreadcrumb(t){if(this.disabled)return;let e={ts:t.ts??new Date().toISOString(),...t};this.breadcrumbBuffer.push(e),this.breadcrumbBuffer.length>R.MAX_BREADCRUMBS&&this.breadcrumbBuffer.shift();}captureException(t,e){if(this.disabled)return;let n=this.buildErrorEntry(t,e);this.useEnvelope?(this.errorBuffer.push(n),this.errorBuffer.length>=this.batchSize&&this.flush()):this.error(n.message,{exception_type:n.exception_type,frames:n.frames});}captureMessage(t,e){if(this.disabled)return;let n={level:e?.level??"info",message:t,platform:typeof document<"u"?"browser":"node",frames:[],breadcrumbs:this.breadcrumbBuffer.slice(),fingerprint:e?.fingerprint,tags:e?.tags,extra:e?.extra,user_id:e?.user_id??this.anonymousId,timestamp:new Date().toISOString()};this.useEnvelope?(this.errorBuffer.push(n),this.errorBuffer.length>=this.batchSize&&this.flush()):this.warn(t);}buildErrorEntry(t,e){let n,r,s=[];if(t instanceof Error)n=t.name,r=t.message,s=J(t.stack);else if(typeof t=="string")r=t;else try{r=JSON.stringify(t);}catch{r=String(t);}return {level:e?.level??"error",platform:typeof document<"u"?"browser":"node",exception_type:n,message:r,frames:s,breadcrumbs:this.breadcrumbBuffer.slice(),fingerprint:e?.fingerprint,tags:e?.tags,extra:e?.extra,user_id:e?.user_id??this.anonymousId,timestamp:new Date().toISOString(),trace_id:this.navTransaction?.trace_id,span_id:this.navTransaction?.span_id}}captureVital(t,e,n){if(this.disabled||!Number.isFinite(e)||e<0)return;let r=n?.rating??W(t,e),s={metric:t,value_ms:t==="cls"?e:Math.round(e),rating:r,route:n?.route??(typeof location<"u"?location.pathname:void 0),page_url:typeof location<"u"?location.href:void 0,session_id:this.sessionId,user_id:this.anonymousId,attributes:n?.attributes,timestamp:new Date().toISOString()};this.useEnvelope?(this.vitalBuffer.push(s),this.vitalBuffer.length>=this.batchSize&&this.flush()):this.track("$web_vital",{properties:{$metric:t.toUpperCase(),$value_ms:s.value_ms,$rating:r}});}startTransaction(t){return this.makeSpan(void 0,t)}startSpan(t){return this.makeSpan(void 0,t)}makeSpan(t,e){let n=e?.trace_id??e?.parent?.trace_id??t?.trace_id??z(),r=V(),s=e?.parent?.span_id??t?.span_id,i=Date.now(),d=new Date(i).toISOString(),a={...e?.attributes??{}},c="unset",u=[],h=false,f=this,g={span_id:r,trace_id:n,setAttribute(p,l){a[p]=l;},setStatus(p){c=p;},addEvent(p,l){u.push({ts:new Date().toISOString(),name:p,attributes:l});},startChild(p){return f.makeSpan(g,p)},finish(){if(h)return;h=true;let p=Date.now(),l={span_id:r,trace_id:n,parent_span_id:s,name:e?.name,op:e?.op,status:c==="unset"?"ok":c,kind:e?.kind,attributes:a,events:u,start_time:d,end_time:new Date(p).toISOString(),timestamp:d,duration_ms:p-i};f.useEnvelope&&(f.spanBuffer.push(l),f.spanBuffer.length>=f.batchSize&&f.flush());}};return g}async flush(){let t=this.logBuffer.splice(0),e=this.eventBuffer.splice(0),n=this.errorBuffer.splice(0),r=this.vitalBuffer.splice(0),s=this.spanBuffer.splice(0),i=[];this.useEnvelope?(t.length>0||e.length>0||n.length>0||r.length>0||s.length>0)&&i.push(this.sendEnvelope(t,e,n,r,s)):(t.length>0&&i.push(this.sendLogs(t)),e.length>0&&i.push(this.sendEvents(e))),await Promise.all(i);}async shutdown(){this.stopTimer(),this.detachPageLifecycle(),this.detachClickCapture(),this.detachFetchInstrumentation(),this.detachXhrInstrumentation(),this.detachGlobalErrorHandlers(),this.navTransaction&&(this.navTransaction.finish(),this.navTransaction=null),await this.flush();}async sendLogs(t){for(let n=0;n<t.length;n+=500){let s=t.slice(n,n+500).map(i=>({severity:i.severity,message:i.message,properties:i.properties,timestamp:i.timestamp}));await this.postWithRetry("/v1/logs",s,i=>{for(let d of i)this.logBuffer.push({severity:d.severity,message:d.message,properties:d.properties,timestamp:d.timestamp});});}}async sendEvents(t){for(let n=0;n<t.length;n+=500){let s=t.slice(n,n+500).map(i=>({event:i.event,distinctId:i.distinctId,properties:i.properties,timestamp:i.timestamp}));await this.postWithRetry("/v1/events",s,i=>{for(let d of i)this.eventBuffer.push({event:d.event,distinctId:d.distinctId,properties:d.properties,timestamp:d.timestamp});});}}async sendEnvelope(t,e,n,r,s){let d=[...t.map(a=>({kind:"log",entry:a})),...e.map(a=>({kind:"event",entry:a})),...n.map(a=>({kind:"error",entry:a})),...r.map(a=>({kind:"vital",entry:a})),...s.map(a=>({kind:"span",entry:a}))];for(let a=0;a<d.length;a+=1e3){let c=d.slice(a,a+1e3),u=JSON.stringify({v:1,sdk:`js@${v}`,sent_at:new Date().toISOString()}),h=c.map(g=>{if(g.kind==="log"){let l=g.entry;return JSON.stringify({type:"log",severity:l.severity,message:l.message,properties:l.properties,timestamp:l.timestamp})}if(g.kind==="event"){let l=g.entry;return JSON.stringify({type:"event",event:l.event,distinctId:l.distinctId,properties:l.properties,timestamp:l.timestamp})}if(g.kind==="error"){let l=g.entry;return JSON.stringify({type:"error",...l})}if(g.kind==="vital"){let l=g.entry;return JSON.stringify({type:"vital",...l})}let p=g.entry;return JSON.stringify({type:"span",...p})}),f=[u,...h].join(`
|
|
6
|
+
`);await this.postEnvelopeWithRetry(f,c);}}async postEnvelopeWithRetry(t,e,n=0){try{let r=await fetch(`${this.endpoint}/v1/envelope`,{method:"POST",headers:{"Content-Type":"application/x-goodlogs-envelope+ndjson",Authorization:`Bearer ${this.apiKey}`,"X-GoodLogs-SDK":`js/${v}`},body:t});if(r.status===429||r.status===503){if(n<4){let s=Math.min(1e3*Math.pow(2,n),8e3),i=Math.random()*500;return await new Promise(d=>setTimeout(d,s+i)),this.postEnvelopeWithRetry(t,e,n+1)}this.onError(new Error(`GoodLogs rate limited after ${n} retries`));return}if(!r.ok){let s=await r.text().catch(()=>"");if(this.onError(new Error(`GoodLogs envelope error ${r.status}: ${s}`)),r.status>=500&&n===0)for(let i of e)i.kind==="log"?this.logBuffer.push(i.entry):i.kind==="event"?this.eventBuffer.push(i.entry):i.kind==="error"?this.errorBuffer.push(i.entry):i.kind==="vital"?this.vitalBuffer.push(i.entry):this.spanBuffer.push(i.entry);}}catch(r){if(n===0)for(let s of e)s.kind==="log"?this.logBuffer.push(s.entry):s.kind==="event"?this.eventBuffer.push(s.entry):s.kind==="error"?this.errorBuffer.push(s.entry):s.kind==="vital"?this.vitalBuffer.push(s.entry):this.spanBuffer.push(s.entry);this.onError(r instanceof Error?r:new Error(String(r)));}}async postWithRetry(t,e,n,r=0){try{let s=await fetch(`${this.endpoint}${t}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,"X-GoodLogs-SDK":`js/${v}`},body:JSON.stringify({batch:e})});if(s.status===429||s.status===503){if(r<4){let d=Math.min(1e3*Math.pow(2,r),8e3),a=Math.random()*500;return await new Promise(c=>setTimeout(c,d+a)),this.postWithRetry(t,e,n,r+1)}this.onError(new Error(`GoodLogs rate limited after ${r} retries`));return}if(!s.ok){let d=await s.text().catch(()=>""),a=new Error(`GoodLogs API error ${s.status}: ${d}`);this.onError(a),s.status>=500&&r===0&&n(e);return}let i=await s.json().catch(()=>null);if(i&&i.rejected&&i.rejected>0){let d=e.slice(i.accepted??0);d.length>0&&n(d);}}catch(s){let i=s instanceof Error?s:new Error(String(s));r===0&&n(e),this.onError(i);}}startTimer(){this.timer=setInterval(()=>{this.flush();},this.flushInterval);let t=this.timer;typeof t?.unref=="function"&&t.unref();}stopTimer(){this.timer!==null&&(clearInterval(this.timer),this.timer=null);}attachPageLifecycle(){typeof document>"u"||(this.visibilityHandler=()=>{document.visibilityState==="hidden"&&this.keepaliveFlush();},document.addEventListener("visibilitychange",this.visibilityHandler));}captureWebVitals(){if(typeof PerformanceObserver>"u")return;let t=(e,n)=>{if(this.useEnvelope)this.captureVital(e.toLowerCase(),n);else {let r=e==="CLS"?"$value":"$value_ms";this.track("$web_vital",{properties:{$metric:e,[r]:e==="CLS"?n:Math.round(n)}});}};try{new PerformanceObserver(e=>{let n=e.getEntries()[0];n&&t("FCP",n.startTime);}).observe({type:"paint",buffered:!0});}catch{}try{new PerformanceObserver(e=>{let n=e.getEntries(),r=n[n.length-1];r&&t("LCP",r.startTime);}).observe({type:"largest-contentful-paint",buffered:!0});}catch{}try{let e=0;if(new PerformanceObserver(n=>{for(let r of n.getEntries())r.hadRecentInput||(e+=r.value);}).observe({type:"layout-shift",buffered:!0}),typeof document<"u"){let n=()=>{e>0&&t("CLS",Math.round(e*1e3)/1e3);};document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&n();});}}catch{}try{if(typeof performance<"u"){let e=performance.getEntriesByType?.("navigation")?.[0];e?.responseStart&&t("TTFB",e.responseStart);}}catch{}try{new PerformanceObserver(e=>{for(let n of e.getEntries()){let r=n.duration;r>0&&t("INP",r);}}).observe({type:"event",buffered:!0});}catch{}}attachPageviewCapture(){if(typeof document>"u"||typeof location>"u")return;this.lastPath=location.pathname,this.track("$pageview"),this.startNavTransaction(this.lastPath,"initial");let t=(e="push")=>{typeof location<"u"&&location.pathname!==this.lastPath&&(this.lastPath=location.pathname,this.track("$pageview"),this.startNavTransaction(this.lastPath,e));};if(typeof history<"u"){let e=history.pushState,n=history.replaceState;history.pushState=function(...r){e.apply(this,r),t("push");},history.replaceState=function(...r){n.apply(this,r),t("replace");};}typeof addEventListener<"u"&&addEventListener("popstate",()=>t("popstate"));}startNavTransaction(t,e){try{this.navTransaction&&(this.navTransaction.finish(),this.navTransaction=null),this.navTransaction=this.startTransaction({op:"navigation",name:t,attributes:{"navigation.type":e,"http.url":typeof location<"u"?location.href:t}});let n=this.navTransaction;setTimeout(()=>{this.navTransaction===n&&(n.finish(),this.navTransaction=null);},3e4);}catch{}}attachGlobalErrorHandlers(){let t=globalThis;typeof t.addEventListener=="function"&&(this.errorHandler||this.rejectionHandler||(this.errorHandler=e=>{let n=e,r=n.error??new Error(n.message??"Uncaught error");try{this.captureException(r,{tags:{source:"window.onerror"},extra:n.filename?{filename:n.filename,lineno:n.lineno,colno:n.colno}:void 0});}catch{}},this.rejectionHandler=e=>{let r=e.reason,s=r;if(!(r instanceof Error)){let i;if(typeof r=="string")i=r;else try{i=JSON.stringify(r);}catch{i=String(r);}s=new Error(i);}try{this.captureException(s,{tags:{source:"unhandledrejection"}});}catch{}},t.addEventListener("error",this.errorHandler),t.addEventListener("unhandledrejection",this.rejectionHandler)));}detachGlobalErrorHandlers(){let t=globalThis;typeof t.removeEventListener=="function"&&(this.errorHandler&&(t.removeEventListener("error",this.errorHandler),this.errorHandler=null),this.rejectionHandler&&(t.removeEventListener("unhandledrejection",this.rejectionHandler),this.rejectionHandler=null));}attachFetchInstrumentation(){if(typeof fetch>"u")return;let t=globalThis;if(this.originalFetch)return;this.originalFetch=t.fetch;let e=t.fetch.bind(globalThis),n=this;t.fetch=function(s,i){let d="",a="GET";if(typeof s=="string")d=s;else if(s&&typeof s=="object"){let h=s;d=h.url??"",a=h.method??a;}let c=i??{};if(c.method?a=String(c.method).toUpperCase():typeof s=="object"&&(a=s.method?.toUpperCase()??a),d.startsWith(n.endpoint))return e(s,c);let u=n.startSpan({op:"http.client",name:`${a} ${d}`,attributes:{"http.method":a,"http.url":d},parent:n.navTransaction??void 0});try{let h=`00-${u.trace_id}-${u.span_id}-01`,f={...c},g=f.headers??{};return f.headers={...g,traceparent:h},e(s,f).then(p=>{let l=p;return typeof l.status=="number"&&u.setAttribute("http.status_code",l.status),u.setStatus(l.ok===!1?"error":"ok"),u.finish(),p}).catch(p=>{throw u.setStatus("error"),u.setAttribute("error.message",p instanceof Error?p.message:String(p)),u.finish(),p})}catch(h){throw u.setStatus("error"),u.finish(),h}};}detachFetchInstrumentation(){this.originalFetch&&(globalThis.fetch=this.originalFetch,this.originalFetch=null);}attachXhrInstrumentation(){let e=globalThis.XMLHttpRequest;if(!e||!e.prototype)return;let n=Symbol.for("goodlogs.xhr.patched"),r=e.prototype;if(r[n]){this.xhrPatched=true;return}let s=r.open,i=r.setRequestHeader,d=r.send,a=this;r.open=function(u,h,...f){return this.__gl_method=typeof u=="string"?u.toUpperCase():"GET",this.__gl_url=typeof h=="string"?h:String(h??""),this.__gl_headers_set=false,s.apply(this,[u,h,...f])},r.setRequestHeader=function(u,h){return this.__gl_headers_set=true,i.apply(this,[u,h])},r.send=function(u){let h=this.__gl_url||"",f=this.__gl_method||"GET";if(h.startsWith(a.endpoint))return d.apply(this,[u]);let g=a.startSpan({op:"http.client",name:`${f} ${h}`,attributes:{"http.method":f,"http.url":h},parent:a.navTransaction??void 0});try{let m=`00-${g.trace_id}-${g.span_id}-01`;i.apply(this,["traceparent",m]);}catch{}let p=(m,E,O)=>{m&&g.setAttribute("http.status_code",m),O&&g.setAttribute("error.message",O),g.setStatus(E?"ok":"error"),g.finish();},l=this.addEventListener;return typeof l=="function"?(l.call(this,"load",()=>{let m=Number(this.status||0);p(m,m>0&&m<500);}),l.call(this,"error",()=>p(0,false,"network error")),l.call(this,"abort",()=>p(0,false,"aborted")),l.call(this,"timeout",()=>p(0,false,"timeout"))):p(0,true),d.apply(this,[u])},r[n]=true,r.__gl_orig_open=s,r.__gl_orig_set_header=i,r.__gl_orig_send=d,this.xhrPatched=true;}detachXhrInstrumentation(){if(!this.xhrPatched)return;let e=globalThis.XMLHttpRequest?.prototype;if(!e)return;let n=Symbol.for("goodlogs.xhr.patched");e.__gl_orig_open&&(e.open=e.__gl_orig_open),e.__gl_orig_set_header&&(e.setRequestHeader=e.__gl_orig_set_header),e.__gl_orig_send&&(e.send=e.__gl_orig_send),delete e.__gl_orig_open,delete e.__gl_orig_set_header,delete e.__gl_orig_send,delete e[n],this.xhrPatched=false;}attachClickCapture(){typeof document>"u"||(this.clickHandler=t=>{let n=t.target?.closest?.("a, button, [data-gl-event], [role='button']");if(!n)return;let r=n.getAttribute?.("data-gl-event"),s=n.tagName?.toLowerCase()??"",i=(n.textContent??"").trim().slice(0,50),d=n.getAttribute?.("href")??void 0,a=(n.className??"").toString().slice(0,80);this.track(r||"$click",{properties:{$element_tag:s,$element_text:i||void 0,$element_href:d,$element_classes:a||void 0}});},document.addEventListener("click",this.clickHandler));}detachClickCapture(){this.clickHandler&&typeof document<"u"&&(document.removeEventListener("click",this.clickHandler),this.clickHandler=null);}detachPageLifecycle(){this.visibilityHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null);}keepaliveFlush(){let t=this.logBuffer.splice(0),e=this.eventBuffer.splice(0),n={"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,"X-GoodLogs-SDK":`js/${v}`};t.length>0&&fetch(`${this.endpoint}/v1/logs`,{method:"POST",headers:n,body:JSON.stringify({batch:t.map(r=>({severity:r.severity,message:r.message,properties:r.properties,timestamp:r.timestamp}))}),keepalive:true}).catch(()=>{}),e.length>0&&fetch(`${this.endpoint}/v1/events`,{method:"POST",headers:n,body:JSON.stringify({batch:e.map(r=>({event:r.event,distinctId:r.distinctId,properties:r.properties,timestamp:r.timestamp}))}),keepalive:true}).catch(()=>{});}sendTelemetry(t,e,n){!this.telemetry||this.disabled||fetch(`${this.endpoint}/v1/telemetry`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,"X-GoodLogs-SDK":`js/${v}`},body:JSON.stringify({source:"sdk",event:t,level:e,metadata:{...n,sdk_version:v}}),keepalive:true}).catch(()=>{});}};R.MAX_BREADCRUMBS=50;var C=R;var $=class{constructor(t){if(!t.apiKey)throw new Error("apiKey is required");if(!t.apiKey.startsWith("gl_sk_"))throw new Error("GoodLogsClient requires a secret API key (gl_sk_...)");this.apiKey=t.apiKey,this.endpoint=y(t.apiKey,t.endpoint),this.timeout=t.timeout??3e4,this.alerts=new L(this),this.slos=new P(this),this.ai=new A(this);}async _request(t,e,n){let r=`${this.endpoint}${e}`,s={Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json"},i=new AbortController,d=setTimeout(()=>i.abort(),this.timeout);try{let a=await fetch(r,{method:t,headers:s,body:n?JSON.stringify(n):void 0,signal:i.signal});if(!a.ok){let c=await a.json().catch(()=>({})),u=c?.error?.message??`API error ${a.status}`;throw new T(a.status,u,c?.error?.code)}return a.status===204?void 0:await a.json()}finally{clearTimeout(d);}}_get(t){return this._request("GET",t)}_post(t,e){return this._request("POST",t,e)}_put(t,e){return this._request("PUT",t,e)}_delete(t){return this._request("DELETE",t)}info(){return this._get("/v1/info")}schema(){return this._get("/v1/schema")}gql(t){return this._post("/v1/gql/query",{q:t})}gqlBatch(t){return this._post("/v1/gql",{queries:t})}gqlAutocomplete(t,e){let n=`/v1/gql/autocomplete?q=${encodeURIComponent(t)}`;return e!==void 0&&(n+=`&cursor=${e}`),this._get(n)}nl2gql(t,e){return this._post("/v1/gql/nl",{prompt:t,mode:e})}},L=class{constructor(t){this.client=t;}list(){return this.client._get("/v1/alerts")}create(t){return this.client._post("/v1/alerts",t)}update(t,e){return this.client._put(`/v1/alerts/${t}`,e)}delete(t){return this.client._delete(`/v1/alerts/${t}`)}mute(t,e){return this.client._post(`/v1/alerts/${t}/mute`,{minutes:e})}},P=class{constructor(t){this.client=t;}list(){return this.client._get("/v1/slos")}create(t){return this.client._post("/v1/slos",t)}update(t,e){return this.client._put(`/v1/slos/${t}`,e)}delete(t){return this.client._delete(`/v1/slos/${t}`)}},A=class{constructor(t){this.client=t;}chat(t,e){return this.client._post("/v1/ai/chat",{message:t,session_id:e})}},T=class extends Error{constructor(e,n,r){super(n);this.status=e;this.code=r;this.name="GoodLogsApiError";}};var q="0.1.0";function Y(o,t){let e=y(t?.apiKey??"",t?.endpoint).replace(/\/+$/,""),n={"Content-Type":"application/json","X-GoodLogs-SDK":q};t?.token&&(n.Authorization=`Bearer ${t.token}`),fetch(`${e}/v1/telemetry`,{method:"POST",headers:n,body:JSON.stringify({source:o.source,event:o.event,level:o.level??"info",metadata:{...o.metadata,sdk_version:q}}),keepalive:true}).catch(()=>{});}function x(o){if(!o)return null;let t=o.trim().split("-");if(t.length!==4)return null;let[e,n,r,s]=t;return e.length!==2||n.length!==32||r.length!==16||s.length!==2||!/^[0-9a-f]+$/.test(n)||!/^[0-9a-f]+$/.test(r)?null:{trace_id:n,parent_span_id:r}}function N(o,t){if(!o)return;let e=o[t]??o[t.toLowerCase()];return Array.isArray(e)?e[0]:e}function Q(o){return function(e,n,r){let s=(e.method??"GET").toUpperCase(),i=e.originalUrl??e.url??"",d=x(N(e.headers,"traceparent")),a=o.startTransaction({op:"http.server",name:`${s} ${i}`,trace_id:d?.trace_id,attributes:{"http.method":s,"http.url":i}}),c=false,u=()=>{if(c)return;c=true;let h=e.route?.path;h&&a.setAttribute("http.route",h);let f=n.statusCode??200;a.setAttribute("http.status_code",f),a.setStatus(f>=500?"error":"ok"),a.finish();};n.on("finish",u),n.on("close",u),e.goodlogs={span:a},r();}}function Z(o){return function(e,n,r){e.addHook("onRequest",(s,i,d)=>{let a=(s.method??"GET").toUpperCase(),c=s.url??"",u=x(N(s.headers,"traceparent")),h=o.startTransaction({op:"http.server",name:`${a} ${c}`,trace_id:u?.trace_id,attributes:{"http.method":a,"http.url":c}});s.__goodlogsSpan=h,d();}),e.addHook("onResponse",(s,i,d)=>{let a=s.__goodlogsSpan;if(a){let c=s.routerPath??s.routeOptions?.url;c&&a.setAttribute("http.route",c);let u=i.statusCode??i.raw?.statusCode??200;a.setAttribute("http.status_code",u),a.setStatus(u>=500?"error":"ok"),a.finish();}d();}),r();}}function tt(o){return {intercept(t,e){let n=t.switchToHttp(),r=n.getRequest(),s=n.getResponse(),i=(r.method??"GET").toUpperCase(),d=r.originalUrl??r.url??"",a=x(N(r.headers,"traceparent")),c=o.startTransaction({op:"http.server",name:`${i} ${d}`,trace_id:a?.trace_id,attributes:{"http.method":i,"http.url":d}}),u=false,h=(g,p)=>{if(u)return;u=true;let l=r.route?.path;l&&c.setAttribute("http.route",l);let m=g??s.statusCode??200;c.setAttribute("http.status_code",m),c.setStatus(p||m>=500?"error":"ok"),c.finish();};s.on("finish",()=>h()),s.on("close",()=>h());let f=e.handle();if(f&&typeof f.subscribe=="function"){let g=f.subscribe({next:()=>{},error:p=>{c.setAttribute("error.message",p instanceof Error?p.message:String(p)),h(500,true);},complete:()=>h()});return {unsubscribe:()=>g.unsubscribe?.()}}return f}}}function et(o){let t=globalThis.process;if(!t||typeof t.on!="function")return;let e=t,n=Symbol.for("goodlogs.node-process.patched");e[n]||(t.on("uncaughtException",r=>{try{o.captureException(r instanceof Error?r:new Error(String(r)),{tags:{source:"uncaughtException"},level:"fatal"}),o.flush();}catch{}}),t.on("unhandledRejection",r=>{try{let s=r instanceof Error?r:new Error(typeof r=="string"?r:(()=>{try{return JSON.stringify(r)}catch{return String(r)}})());o.captureException(s,{tags:{source:"unhandledRejection"}});}catch{}}),e[n]=true);}var H=globalThis.URL;function k(o){return !!H&&o instanceof H}var j=Symbol.for("goodlogs.node-http.patched");function nt(...o){let t=o[0],e=o[1],n="GET",r="";if(typeof t=="string")r=t,e&&typeof e=="object"&&!k(e)&&(n=String(e.method??n).toUpperCase());else if(k(t))r=t.toString(),e&&typeof e=="object"&&!k(e)&&(n=String(e.method??n).toUpperCase());else if(t&&typeof t=="object"){let i=t;n=String(i.method??n).toUpperCase();let d=(i.protocol??"http:").replace(":",""),a=i.hostname??i.host??"localhost",c=i.port?`:${i.port}`:"";r=`${d}://${a}${c}${i.path??"/"}`;}return {method:n,url:r,isOurs:i=>!!i&&r.startsWith(i)}}function rt(o,t,e){let n=o[0]&&typeof o[0]=="object"&&!k(o[0])?o[0]:o[1]&&typeof o[1]=="object"&&!k(o[1])?o[1]:void 0;n&&(n.headers||(n.headers={}),!(t in n.headers)&&!(t.toLowerCase()in n.headers)&&(n.headers[t]=e));}function st(o,t){let e=t?.endpoint??o.endpoint??"",n=r=>{let s=r;if(s[j])return;s[j]=true;let i=r.request.bind(r);r.request=function(...a){let{method:c,url:u,isOurs:h}=nt(...a);if(!u||h(e))return i(...a);let f=o.startTransaction({op:"http.client",name:`${c} ${u}`,attributes:{"http.method":c,"http.url":u}});rt(a,"traceparent",`00-${f.trace_id}-${f.span_id}-01`);let g=false,p=(m,E)=>{g||(g=true,typeof m=="number"&&f.setAttribute("http.status_code",m),E?(f.setAttribute("error.message",E.message),f.setStatus("error")):f.setStatus(typeof m=="number"&&m>=500?"error":"ok"),f.finish());},l=i(...a);return l.on("response",m=>p(m.statusCode)),l.on("error",m=>p(void 0,m)),l.on("close",()=>p()),l};};if(typeof S=="function"){try{let r=S("http");n(r);}catch{}try{let r=S("https");n(r);}catch{}}}
|
|
7
|
+
export{C as GoodLogs,T as GoodLogsApiError,$ as GoodLogsClient,I as REGION_URLS,Q as goodlogsExpress,Z as goodlogsFastify,tt as goodlogsNestInterceptor,st as instrumentNodeHttp,et as instrumentNodeProcess,x as parseTraceparent,y as resolveEndpoint,B as resolveRegion,Y as sendTelemetry};
|
package/dist/replay.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var C="https://cdn.jsdelivr.net/npm/rrweb@2.0.0-alpha.18/dist/rrweb.min.js";async function $(n,e={}){if(typeof document>"u")return null;let i=e.sampleRate??1;if(i<1&&Math.random()>i)return null;let s=e.rrwebRecord??await P(e.cdnUrl??C);if(!s)return null;let t=n.endpoint,r=n.apiKey,a=n.sessionId,v=n.getDistinctId(),h=e.flushIntervalMs??5e3,y=e.flushBytes??5e5,c=[],d=0,w=0,f=false,u=false;m(t,r,{session_id:a,distinct_id:v,start_url:typeof location<"u"?location.href:null,last_url:typeof location<"u"?location.href:null},e.onError);let l=async()=>{if(c.length===0)return;let o=c,I=o[0].timestamp,g=o[o.length-1].timestamp,S=o.length;c=[],d=0;let E=w++;try{let p=JSON.stringify(o),T=await O(p),B=`${t}/v1/replay/chunks?session_id=${encodeURIComponent(a)}&seq=${E}&start_ts=${encodeURIComponent(new Date(I).toISOString())}&end_ts=${encodeURIComponent(new Date(g).toISOString())}&event_count=${S}`;await fetch(B,{method:"POST",headers:{Authorization:`Bearer ${r}`,"Content-Type":"application/gzip","Content-Encoding":"gzip"},body:T,keepalive:!0});}catch(p){e.onError?.(p);}m(t,r,{session_id:a,last_url:typeof location<"u"?location.href:null,last_activity_at:new Date(g).toISOString(),has_error:f||void 0},e.onError);},k=s({emit:o=>{u||(c.push(o),d+=256,d>=y&&l());},checkoutEveryNms:6e4,maskAllInputs:e.maskAllInputs??true,blockSelector:e.blockSelector??"[data-gl-block]",maskTextSelector:e.maskTextSelector??"[data-gl-mask]"}),R=setInterval(()=>{l();},h),b=()=>{document?.visibilityState==="hidden"&&l();};document.addEventListener("visibilitychange",b);let _=setInterval(()=>{globalThis.__gl_replay_has_error__&&(f=true);},1e3);return {sessionId:a,flush:l,stop:()=>{if(!u){u=true,clearInterval(R),clearInterval(_),document?.removeEventListener("visibilitychange",b);try{k();}catch(o){e.onError?.(o);}l(),m(t,r,{session_id:a,ended_at:new Date().toISOString()},e.onError);}}}}async function m(n,e,i,s){try{await fetch(`${n}/v1/replay/sessions`,{method:"POST",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify(i),keepalive:!0});}catch(t){s?.(t);}}async function O(n){if(typeof CompressionStream>"u"||typeof Blob>"u"||typeof Response>"u")return n;let i=new Blob([n]).stream().pipeThrough(new CompressionStream("gzip")),s=await new Response(i).arrayBuffer();return new Blob([s],{type:"application/gzip"})}async function P(n){let e=globalThis;if(e.rrweb?.record)return e.rrweb.record;try{return await new Promise((i,s)=>{let t=globalThis.document;if(!t){s(new Error("no document"));return}let r=t.createElement("script");r.src=n,r.async=!0,r.onload=()=>i(),r.onerror=()=>s(new Error(`failed to load ${n}`)),t.head.appendChild(r);}),e.rrweb?.record??null}catch{return null}}
|
|
2
|
+
exports.startReplay=$;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { G as GoodLogs } from './client-w3t1Yzjd.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Session Replay (rrweb) — optional, lazy-loaded.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* import { GoodLogs } from "@aj-2000-test/goodlogs-sdk";
|
|
8
|
+
* import { startReplay } from "@aj-2000-test/goodlogs-sdk/replay";
|
|
9
|
+
*
|
|
10
|
+
* const gl = new GoodLogs({ apiKey: "gl_pk_..." });
|
|
11
|
+
* startReplay(gl);
|
|
12
|
+
*
|
|
13
|
+
* Capture is *not* a video — it's the rrweb DOM-mutation stream gzipped
|
|
14
|
+
* and shipped to /v1/replay/chunks. See docs/storage-design.md for storage.
|
|
15
|
+
*
|
|
16
|
+
* rrweb is loaded from a CDN at runtime so the core SDK bundle stays small.
|
|
17
|
+
* Pass a local `rrwebRecord` instead if you bundle rrweb yourself.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
interface RrwebRecord {
|
|
21
|
+
(opts: {
|
|
22
|
+
emit: (event: RrwebEvent, isCheckout?: boolean) => void;
|
|
23
|
+
checkoutEveryNms?: number;
|
|
24
|
+
maskAllInputs?: boolean;
|
|
25
|
+
maskInputOptions?: Record<string, boolean>;
|
|
26
|
+
blockClass?: string;
|
|
27
|
+
blockSelector?: string;
|
|
28
|
+
ignoreClass?: string;
|
|
29
|
+
maskTextClass?: string;
|
|
30
|
+
maskTextSelector?: string;
|
|
31
|
+
sampling?: Record<string, unknown>;
|
|
32
|
+
}): () => void;
|
|
33
|
+
}
|
|
34
|
+
interface RrwebEvent {
|
|
35
|
+
type: number;
|
|
36
|
+
data: unknown;
|
|
37
|
+
timestamp: number;
|
|
38
|
+
}
|
|
39
|
+
interface ReplayOptions {
|
|
40
|
+
/** Provide rrweb's `record` yourself (bundled). Skips CDN load. */
|
|
41
|
+
rrwebRecord?: RrwebRecord;
|
|
42
|
+
/** CDN URL for rrweb when `rrwebRecord` is not provided. */
|
|
43
|
+
cdnUrl?: string;
|
|
44
|
+
/** Flush queued events every N ms (default 5000). */
|
|
45
|
+
flushIntervalMs?: number;
|
|
46
|
+
/** Force flush when queue reaches this size in bytes (default 500_000). */
|
|
47
|
+
flushBytes?: number;
|
|
48
|
+
/** Sample rate 0..1 (default 1 — always record). Errors override sampling. */
|
|
49
|
+
sampleRate?: number;
|
|
50
|
+
/** Block any DOM matching this CSS selector. */
|
|
51
|
+
blockSelector?: string;
|
|
52
|
+
/** Mask text of nodes matching this selector. */
|
|
53
|
+
maskTextSelector?: string;
|
|
54
|
+
/** Mask all <input>/<textarea> text by default. */
|
|
55
|
+
maskAllInputs?: boolean;
|
|
56
|
+
/** Custom logger for errors. */
|
|
57
|
+
onError?: (e: unknown) => void;
|
|
58
|
+
}
|
|
59
|
+
interface ReplayHandle {
|
|
60
|
+
stop: () => void;
|
|
61
|
+
flush: () => Promise<void>;
|
|
62
|
+
sessionId: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Start recording. Returns a handle with `stop()` and `flush()`.
|
|
66
|
+
* Calling more than once is a no-op (returns the existing handle).
|
|
67
|
+
*/
|
|
68
|
+
declare function startReplay(gl: GoodLogs, options?: ReplayOptions): Promise<ReplayHandle | null>;
|
|
69
|
+
|
|
70
|
+
export { type ReplayOptions, type RrwebEvent, startReplay };
|
package/dist/replay.d.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { G as GoodLogs } from './client-w3t1Yzjd.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Session Replay (rrweb) — optional, lazy-loaded.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* import { GoodLogs } from "@aj-2000-test/goodlogs-sdk";
|
|
8
|
+
* import { startReplay } from "@aj-2000-test/goodlogs-sdk/replay";
|
|
9
|
+
*
|
|
10
|
+
* const gl = new GoodLogs({ apiKey: "gl_pk_..." });
|
|
11
|
+
* startReplay(gl);
|
|
12
|
+
*
|
|
13
|
+
* Capture is *not* a video — it's the rrweb DOM-mutation stream gzipped
|
|
14
|
+
* and shipped to /v1/replay/chunks. See docs/storage-design.md for storage.
|
|
15
|
+
*
|
|
16
|
+
* rrweb is loaded from a CDN at runtime so the core SDK bundle stays small.
|
|
17
|
+
* Pass a local `rrwebRecord` instead if you bundle rrweb yourself.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
interface RrwebRecord {
|
|
21
|
+
(opts: {
|
|
22
|
+
emit: (event: RrwebEvent, isCheckout?: boolean) => void;
|
|
23
|
+
checkoutEveryNms?: number;
|
|
24
|
+
maskAllInputs?: boolean;
|
|
25
|
+
maskInputOptions?: Record<string, boolean>;
|
|
26
|
+
blockClass?: string;
|
|
27
|
+
blockSelector?: string;
|
|
28
|
+
ignoreClass?: string;
|
|
29
|
+
maskTextClass?: string;
|
|
30
|
+
maskTextSelector?: string;
|
|
31
|
+
sampling?: Record<string, unknown>;
|
|
32
|
+
}): () => void;
|
|
33
|
+
}
|
|
34
|
+
interface RrwebEvent {
|
|
35
|
+
type: number;
|
|
36
|
+
data: unknown;
|
|
37
|
+
timestamp: number;
|
|
38
|
+
}
|
|
39
|
+
interface ReplayOptions {
|
|
40
|
+
/** Provide rrweb's `record` yourself (bundled). Skips CDN load. */
|
|
41
|
+
rrwebRecord?: RrwebRecord;
|
|
42
|
+
/** CDN URL for rrweb when `rrwebRecord` is not provided. */
|
|
43
|
+
cdnUrl?: string;
|
|
44
|
+
/** Flush queued events every N ms (default 5000). */
|
|
45
|
+
flushIntervalMs?: number;
|
|
46
|
+
/** Force flush when queue reaches this size in bytes (default 500_000). */
|
|
47
|
+
flushBytes?: number;
|
|
48
|
+
/** Sample rate 0..1 (default 1 — always record). Errors override sampling. */
|
|
49
|
+
sampleRate?: number;
|
|
50
|
+
/** Block any DOM matching this CSS selector. */
|
|
51
|
+
blockSelector?: string;
|
|
52
|
+
/** Mask text of nodes matching this selector. */
|
|
53
|
+
maskTextSelector?: string;
|
|
54
|
+
/** Mask all <input>/<textarea> text by default. */
|
|
55
|
+
maskAllInputs?: boolean;
|
|
56
|
+
/** Custom logger for errors. */
|
|
57
|
+
onError?: (e: unknown) => void;
|
|
58
|
+
}
|
|
59
|
+
interface ReplayHandle {
|
|
60
|
+
stop: () => void;
|
|
61
|
+
flush: () => Promise<void>;
|
|
62
|
+
sessionId: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Start recording. Returns a handle with `stop()` and `flush()`.
|
|
66
|
+
* Calling more than once is a no-op (returns the existing handle).
|
|
67
|
+
*/
|
|
68
|
+
declare function startReplay(gl: GoodLogs, options?: ReplayOptions): Promise<ReplayHandle | null>;
|
|
69
|
+
|
|
70
|
+
export { type ReplayOptions, type RrwebEvent, startReplay };
|
package/dist/replay.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var C="https://cdn.jsdelivr.net/npm/rrweb@2.0.0-alpha.18/dist/rrweb.min.js";async function $(n,e={}){if(typeof document>"u")return null;let i=e.sampleRate??1;if(i<1&&Math.random()>i)return null;let s=e.rrwebRecord??await P(e.cdnUrl??C);if(!s)return null;let t=n.endpoint,r=n.apiKey,a=n.sessionId,v=n.getDistinctId(),h=e.flushIntervalMs??5e3,y=e.flushBytes??5e5,c=[],d=0,w=0,f=false,u=false;m(t,r,{session_id:a,distinct_id:v,start_url:typeof location<"u"?location.href:null,last_url:typeof location<"u"?location.href:null},e.onError);let l=async()=>{if(c.length===0)return;let o=c,I=o[0].timestamp,g=o[o.length-1].timestamp,S=o.length;c=[],d=0;let E=w++;try{let p=JSON.stringify(o),T=await O(p),B=`${t}/v1/replay/chunks?session_id=${encodeURIComponent(a)}&seq=${E}&start_ts=${encodeURIComponent(new Date(I).toISOString())}&end_ts=${encodeURIComponent(new Date(g).toISOString())}&event_count=${S}`;await fetch(B,{method:"POST",headers:{Authorization:`Bearer ${r}`,"Content-Type":"application/gzip","Content-Encoding":"gzip"},body:T,keepalive:!0});}catch(p){e.onError?.(p);}m(t,r,{session_id:a,last_url:typeof location<"u"?location.href:null,last_activity_at:new Date(g).toISOString(),has_error:f||void 0},e.onError);},k=s({emit:o=>{u||(c.push(o),d+=256,d>=y&&l());},checkoutEveryNms:6e4,maskAllInputs:e.maskAllInputs??true,blockSelector:e.blockSelector??"[data-gl-block]",maskTextSelector:e.maskTextSelector??"[data-gl-mask]"}),R=setInterval(()=>{l();},h),b=()=>{document?.visibilityState==="hidden"&&l();};document.addEventListener("visibilitychange",b);let _=setInterval(()=>{globalThis.__gl_replay_has_error__&&(f=true);},1e3);return {sessionId:a,flush:l,stop:()=>{if(!u){u=true,clearInterval(R),clearInterval(_),document?.removeEventListener("visibilitychange",b);try{k();}catch(o){e.onError?.(o);}l(),m(t,r,{session_id:a,ended_at:new Date().toISOString()},e.onError);}}}}async function m(n,e,i,s){try{await fetch(`${n}/v1/replay/sessions`,{method:"POST",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify(i),keepalive:!0});}catch(t){s?.(t);}}async function O(n){if(typeof CompressionStream>"u"||typeof Blob>"u"||typeof Response>"u")return n;let i=new Blob([n]).stream().pipeThrough(new CompressionStream("gzip")),s=await new Response(i).arrayBuffer();return new Blob([s],{type:"application/gzip"})}async function P(n){let e=globalThis;if(e.rrweb?.record)return e.rrweb.record;try{return await new Promise((i,s)=>{let t=globalThis.document;if(!t){s(new Error("no document"));return}let r=t.createElement("script");r.src=n,r.async=!0,r.onload=()=>i(),r.onerror=()=>s(new Error(`failed to load ${n}`)),t.head.appendChild(r);}),e.rrweb?.record??null}catch{return null}}
|
|
2
|
+
export{$ as startReplay};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aj-2000-test/goodlogs-sdk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "GoodLogs SDK —
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "GoodLogs SDK — ingest logs/events + programmatic API client for queries, alerts, AI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
7
7
|
"module": "dist/index.js",
|
|
@@ -11,11 +11,21 @@
|
|
|
11
11
|
"import": "./dist/index.js",
|
|
12
12
|
"require": "./dist/index.cjs",
|
|
13
13
|
"types": "./dist/index.d.ts"
|
|
14
|
+
},
|
|
15
|
+
"./replay": {
|
|
16
|
+
"import": "./dist/replay.js",
|
|
17
|
+
"require": "./dist/replay.cjs",
|
|
18
|
+
"types": "./dist/replay.d.ts"
|
|
14
19
|
}
|
|
15
20
|
},
|
|
16
21
|
"files": [
|
|
17
|
-
"dist"
|
|
22
|
+
"dist",
|
|
23
|
+
"bin"
|
|
18
24
|
],
|
|
25
|
+
"bin": {
|
|
26
|
+
"goodlogs": "bin/goodlogs.cjs"
|
|
27
|
+
},
|
|
28
|
+
"sideEffects": false,
|
|
19
29
|
"scripts": {
|
|
20
30
|
"build": "tsup",
|
|
21
31
|
"dev": "tsup --watch",
|