@aj-2000-test/goodlogs-sdk 0.5.4 → 0.5.6
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/{client-CdAY1YSZ.d.cts → client-D5LyyDBY.d.cts} +23 -1
- package/dist/{client-CdAY1YSZ.d.ts → client-D5LyyDBY.d.ts} +23 -1
- package/dist/index.cjs +6 -6
- package/dist/index.d.cts +52 -3
- package/dist/index.d.ts +52 -3
- package/dist/index.js +6 -6
- package/dist/memory.d.cts +1 -1
- package/dist/memory.d.ts +1 -1
- package/dist/profiling.d.cts +1 -1
- package/dist/profiling.d.ts +1 -1
- package/dist/react.cjs +1 -1
- package/dist/react.d.cts +20 -2
- package/dist/react.d.ts +20 -2
- package/dist/react.js +1 -1
- package/dist/replay.cjs +1 -1
- package/dist/replay.d.cts +1 -1
- package/dist/replay.d.ts +1 -1
- package/dist/replay.js +1 -1
- package/package.json +1 -1
|
@@ -38,6 +38,15 @@ interface GoodLogsOptions {
|
|
|
38
38
|
/** Called before each error is captured. Return the (optionally modified) error to send it,
|
|
39
39
|
* or return null to drop it. Useful for filtering, PII scrubbing, or enriching errors. */
|
|
40
40
|
beforeSend?: (error: ErrorEntry) => ErrorEntry | null;
|
|
41
|
+
/** Enable feature flag polling. Fetches flag definitions from the API and evaluates locally.
|
|
42
|
+
* Requires an API key with `flags:read` scope (public keys have this by default). */
|
|
43
|
+
flags?: boolean | FeatureFlagOptions;
|
|
44
|
+
}
|
|
45
|
+
interface FeatureFlagOptions {
|
|
46
|
+
/** Poll interval in ms (default: 30000 = 30s) */
|
|
47
|
+
pollInterval?: number;
|
|
48
|
+
/** Initial user properties for flag evaluation. Can also be set via identify(). */
|
|
49
|
+
properties?: Record<string, unknown>;
|
|
41
50
|
}
|
|
42
51
|
interface LogEntry {
|
|
43
52
|
severity: Severity;
|
|
@@ -158,6 +167,7 @@ declare class GoodLogs {
|
|
|
158
167
|
private rejectionHandler;
|
|
159
168
|
private anonymousId;
|
|
160
169
|
private sessionId;
|
|
170
|
+
private flagClient;
|
|
161
171
|
constructor(options: GoodLogsOptions);
|
|
162
172
|
log(severity: Severity, message: string, properties?: Record<string, unknown>): void;
|
|
163
173
|
debug(message: string, properties?: Record<string, unknown>): void;
|
|
@@ -198,6 +208,18 @@ declare class GoodLogs {
|
|
|
198
208
|
}): void;
|
|
199
209
|
/** Get the current user properties. */
|
|
200
210
|
getUser(): Record<string, unknown>;
|
|
211
|
+
/** Check if a boolean flag is enabled.
|
|
212
|
+
* @param properties - Optional per-call properties for server-side use (merged with setUser). */
|
|
213
|
+
isEnabled(flagKey: string, defaultValue?: boolean, properties?: Record<string, unknown>): boolean;
|
|
214
|
+
/** Get a flag's resolved value (for multivariate / string / number flags).
|
|
215
|
+
* @param properties - Optional per-call properties for server-side use (merged with setUser). */
|
|
216
|
+
getVariant<T = unknown>(flagKey: string, defaultValue: T, properties?: Record<string, unknown>): T;
|
|
217
|
+
/** Get all flag values as a plain object. */
|
|
218
|
+
getAllFlags(): Record<string, unknown>;
|
|
219
|
+
/** Register a callback for when a flag value changes. Returns unsubscribe function. */
|
|
220
|
+
onFlagChange(flagKey: string, callback: (value: unknown) => void): () => void;
|
|
221
|
+
/** Wait until feature flags are loaded from the API. */
|
|
222
|
+
flagsReady(): Promise<void>;
|
|
201
223
|
track(event: string, properties?: Record<string, unknown> & {
|
|
202
224
|
distinctId?: string;
|
|
203
225
|
}): void;
|
|
@@ -270,4 +292,4 @@ declare class GoodLogs {
|
|
|
270
292
|
private sendTelemetry;
|
|
271
293
|
}
|
|
272
294
|
|
|
273
|
-
export { type CaptureContext as C, type ErrorBreadcrumb as E, GoodLogs as G, type LogEntry as L, type Severity as S, type ErrorEntry as a, type ErrorFrame as b, type EventEntry as c, type GoodLogsOptions as d };
|
|
295
|
+
export { type CaptureContext as C, type ErrorBreadcrumb as E, type FeatureFlagOptions as F, GoodLogs as G, type LogEntry as L, type Severity as S, type ErrorEntry as a, type ErrorFrame as b, type EventEntry as c, type GoodLogsOptions as d };
|
|
@@ -38,6 +38,15 @@ interface GoodLogsOptions {
|
|
|
38
38
|
/** Called before each error is captured. Return the (optionally modified) error to send it,
|
|
39
39
|
* or return null to drop it. Useful for filtering, PII scrubbing, or enriching errors. */
|
|
40
40
|
beforeSend?: (error: ErrorEntry) => ErrorEntry | null;
|
|
41
|
+
/** Enable feature flag polling. Fetches flag definitions from the API and evaluates locally.
|
|
42
|
+
* Requires an API key with `flags:read` scope (public keys have this by default). */
|
|
43
|
+
flags?: boolean | FeatureFlagOptions;
|
|
44
|
+
}
|
|
45
|
+
interface FeatureFlagOptions {
|
|
46
|
+
/** Poll interval in ms (default: 30000 = 30s) */
|
|
47
|
+
pollInterval?: number;
|
|
48
|
+
/** Initial user properties for flag evaluation. Can also be set via identify(). */
|
|
49
|
+
properties?: Record<string, unknown>;
|
|
41
50
|
}
|
|
42
51
|
interface LogEntry {
|
|
43
52
|
severity: Severity;
|
|
@@ -158,6 +167,7 @@ declare class GoodLogs {
|
|
|
158
167
|
private rejectionHandler;
|
|
159
168
|
private anonymousId;
|
|
160
169
|
private sessionId;
|
|
170
|
+
private flagClient;
|
|
161
171
|
constructor(options: GoodLogsOptions);
|
|
162
172
|
log(severity: Severity, message: string, properties?: Record<string, unknown>): void;
|
|
163
173
|
debug(message: string, properties?: Record<string, unknown>): void;
|
|
@@ -198,6 +208,18 @@ declare class GoodLogs {
|
|
|
198
208
|
}): void;
|
|
199
209
|
/** Get the current user properties. */
|
|
200
210
|
getUser(): Record<string, unknown>;
|
|
211
|
+
/** Check if a boolean flag is enabled.
|
|
212
|
+
* @param properties - Optional per-call properties for server-side use (merged with setUser). */
|
|
213
|
+
isEnabled(flagKey: string, defaultValue?: boolean, properties?: Record<string, unknown>): boolean;
|
|
214
|
+
/** Get a flag's resolved value (for multivariate / string / number flags).
|
|
215
|
+
* @param properties - Optional per-call properties for server-side use (merged with setUser). */
|
|
216
|
+
getVariant<T = unknown>(flagKey: string, defaultValue: T, properties?: Record<string, unknown>): T;
|
|
217
|
+
/** Get all flag values as a plain object. */
|
|
218
|
+
getAllFlags(): Record<string, unknown>;
|
|
219
|
+
/** Register a callback for when a flag value changes. Returns unsubscribe function. */
|
|
220
|
+
onFlagChange(flagKey: string, callback: (value: unknown) => void): () => void;
|
|
221
|
+
/** Wait until feature flags are loaded from the API. */
|
|
222
|
+
flagsReady(): Promise<void>;
|
|
201
223
|
track(event: string, properties?: Record<string, unknown> & {
|
|
202
224
|
distinctId?: string;
|
|
203
225
|
}): void;
|
|
@@ -270,4 +292,4 @@ declare class GoodLogs {
|
|
|
270
292
|
private sendTelemetry;
|
|
271
293
|
}
|
|
272
294
|
|
|
273
|
-
export { type CaptureContext as C, type ErrorBreadcrumb as E, GoodLogs as G, type LogEntry as L, type Severity as S, type ErrorEntry as a, type ErrorFrame as b, type EventEntry as c, type GoodLogsOptions as d };
|
|
295
|
+
export { type CaptureContext as C, type ErrorBreadcrumb as E, type FeatureFlagOptions as F, GoodLogs as G, type LogEntry as L, type Severity as S, type ErrorEntry as a, type ErrorFrame as b, type EventEntry as c, type GoodLogsOptions as d };
|
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
'use strict';var
|
|
2
|
-
`);if(!e)return;for(let t=3;t<Math.min(e.length,8);t++){let n=e[t]?.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
|
|
3
|
-
`)){let n=t.trim();if(!n||n.startsWith("Error")||n.startsWith("at Error"))continue;let r=/^at\s+(?:(.+?)\s+\()?(.+?):(\d+):(\d+)\)?$/.exec(n);if(r){let
|
|
1
|
+
'use strict';var R=(s=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(s,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):s)(function(s){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+s+'" is not supported')});function H(s){let e=s.split("_");return e.length>=4&&e[0]==="gl"?e[2]:"eu"}function D(s,e){return s==="eu"&&(!e||e==="production")?"https://api.goodlogs.dev":s==="eu"?`https://api-${e}.goodlogs.dev`:!e||e==="production"?`https://api-${s}.goodlogs.dev`:`https://api-${s}-${e}.goodlogs.dev`}function y(s,e,t){if(e)return e;let n=H(s);return D(n,t)}var K=(()=>{let s=[];for(let e=0;e<256;e++){let t=e;for(let n=0;n<8;n++)t=t&1?3988292384^t>>>1:t>>>1;s[e]=t;}return s})();function j(s){let e=4294967295;for(let t=0;t<s.length;t++)e=K[(e^s.charCodeAt(t))&255]^e>>>8;return (e^4294967295)>>>0}function k(s,e,t){if(!s.enabled)return s.default_value;if(s.overrides&&e in s.overrides)return s.overrides[e];for(let n of s.rules)if(V(n.conditions,t)){if(n.rollout_percentage<100&&j(`${s.key}:${e}`)%100>=n.rollout_percentage)continue;return s.variants.length>0&&n.variant?W(s.variants,s.key,e):n.value}return s.default_value}function V(s,e){return s.length===0?true:s.every(t=>X(t,e))}function X(s,e){let t=e[s.property],n=s.operator;if(n==="is_set")return t!=null;if(n==="is_not_set")return t==null;if(n==="eq")return C(t,s.value);if(n==="neq")return !C(t,s.value);let r=q(t),i=q(s.value);return n==="gt"?r!==null&&i!==null&&r>i:n==="gte"?r!==null&&i!==null&&r>=i:n==="lt"?r!==null&&i!==null&&r<i:n==="lte"?r!==null&&i!==null&&r<=i:n==="in"&&Array.isArray(s.value)?s.value.some(o=>C(t,o)):n==="not_in"&&Array.isArray(s.value)?!s.value.some(o=>C(t,o)):n==="contains"?String(t??"").toLowerCase().includes(String(s.value??"").toLowerCase()):n==="not_contains"?!String(t??"").toLowerCase().includes(String(s.value??"").toLowerCase()):false}function C(s,e){if(s===e)return true;let t=String(s??"").toLowerCase(),n=String(e??"").toLowerCase();return t===n}function q(s){if(typeof s=="number")return s;if(typeof s=="string"){let e=parseFloat(s);return isNaN(e)?null:e}return null}function W(s,e,t){if(s.length===0)return null;let n=j(`${e}:variant:${t}`)%1e4,r=0;for(let i of s)if(r+=i.weight*100,n<r)return i.value;return s[s.length-1]?.value??null}var w=class{constructor(e,t,n=3e4){this.flags=new Map;this.version=0;this.distinctId="";this.properties={};this.listeners=new Map;this.timer=null;this.ready=false;this.readyCallbacks=[];this.endpoint=e,this.apiKey=t,this.pollInterval=n;}async start(){await this.fetchAll(),this.ready=true;for(let e of this.readyCallbacks)e();this.readyCallbacks=[],this.timer=setInterval(()=>this.poll(),this.pollInterval);}stop(){this.timer&&(clearInterval(this.timer),this.timer=null);}onReady(){return this.ready?Promise.resolve():new Promise(e=>this.readyCallbacks.push(e))}setUser(e,t){this.distinctId=e,t&&(this.properties={...t});}isEnabled(e,t=false,n){let r=this.flags.get(e);if(!r)return t;let i=n?{...this.properties,...n}:this.properties,o=k(r,this.distinctId,i);return o===true||o==="true"}getVariant(e,t,n){let r=this.flags.get(e);if(!r)return t;let i=n?{...this.properties,...n}:this.properties;return k(r,this.distinctId,i)??t}getAllFlags(){let e={};for(let[t,n]of this.flags)e[t]=k(n,this.distinctId,this.properties);return e}onFlagChange(e,t){let n=this.listeners.get(e);return n||(n=new Set,this.listeners.set(e,n)),n.add(t),()=>n.delete(t)}async fetchAll(){try{let e=await fetch(`${this.endpoint}/v1/flags`,{headers:{"x-api-key":this.apiKey}});if(!e.ok)return;let t=await e.json();this.applyUpdate(t.flags??[],t.version??0);}catch{}}async poll(){try{let e=await fetch(`${this.endpoint}/v1/flags?since_version=${this.version}`,{headers:{"x-api-key":this.apiKey}});if(e.status===304||!e.ok)return;let t=await e.json();this.applyUpdate(t.flags??[],t.version??0);}catch{}}applyUpdate(e,t){let n=new Map;for(let r of e){let i=this.flags.get(r.key);i&&n.set(r.key,k(i,this.distinctId,this.properties));}for(let r of e)this.flags.set(r.key,r);t>this.version&&(this.version=t);for(let r of e){let i=n.get(r.key),o=k(r,this.distinctId,this.properties);i!==void 0&&i!==o&&this.listeners.get(r.key)?.forEach(a=>{try{a(o);}catch{}});}}};var J=5e3,z=50,v="0.5.6",$="gl_anon_id",_="gl_session_id";function b(){return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,s=>{let e=Math.random()*16|0;return (s==="x"?e:e&3|8).toString(16)})}function Y(){let s={$goodlogs_sdk:"js",$goodlogs_sdk_version:v};return typeof navigator>"u"||(typeof screen<"u"&&(s.$screen=`${screen.width}x${screen.height}`),typeof navigator<"u"&&(s.$language=navigator.language??""),typeof location<"u"&&(s.$url=location.href,s.$path=location.pathname,s.$page=location.pathname.split("/").filter(Boolean).pop()||"/"),typeof document<"u"&&(document.referrer&&(s.$referrer=document.referrer),document.title&&(s.$title=document.title))),s}function Q(s,e){let t={$session_id:s,$distinct_id:e,$goodlogs_sdk:"js",$goodlogs_sdk_version:v};return typeof navigator>"u"||typeof location<"u"&&(t.$url=location.href,t.$path=location.pathname),t}function Z(s,e,t,n,r){let i=Q(s,e);return t&&(i.$release=t),i.$environment=n,r.email&&(i.$user_email=r.email),r.name&&(i.$user_name=r.name),i}function ee(){if(!(typeof document<"u"))try{let e=new Error().stack?.split(`
|
|
2
|
+
`);if(!e)return;for(let t=3;t<Math.min(e.length,8);t++){let n=e[t]?.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 i=r[1]||"<anonymous>",o=r[2]?.replace(/^.*[/\\]/,"")??"",a=r[3];return `${i}@${o}:${a}`}}}catch{}}function te(s){let e=[],t=s;for(;t&&t.tagName;){let n=t.tagName.toLowerCase();if(n==="html"||n==="body"){e.unshift(n);break}if(t.id){e.unshift(`#${t.id}`);break}let r=1,i=t;for(;i?.previousElementSibling;)i.previousElementSibling.tagName?.toLowerCase()===n&&r++,i=i.previousElementSibling;e.unshift(r>1?`${n}:nth-of-type(${r})`:n),t=t.parentElement;}return e.join(" > ").slice(0,200)}function ne(){if(typeof localStorage<"u"){let s=localStorage.getItem($);if(s)return s;let e=b();return localStorage.setItem($,e),e}return b()}function re(){if(typeof sessionStorage<"u"){let s=sessionStorage.getItem(_);if(s)return s;let e=b();return sessionStorage.setItem(_,e),e}return b()}function ie(){let s="";for(let e=0;e<32;e++)s+=(Math.random()*16|0).toString(16);return s}function se(){let s="";for(let e=0;e<16;e++)s+=(Math.random()*16|0).toString(16);return s}function oe(s,e){switch(s){case "lcp":return e<=2500?"good":e<=4e3?"needs-improvement":"poor";case "inp":return e<=200?"good":e<=500?"needs-improvement":"poor";case "cls":return e<=.1?"good":e<=.25?"needs-improvement":"poor";case "fcp":return e<=1800?"good":e<=3e3?"needs-improvement":"poor";case "ttfb":return e<=800?"good":e<=1800?"needs-improvement":"poor";case "dns":return e<=20?"good":e<=100?"needs-improvement":"poor";case "tcp":return e<=50?"good":e<=200?"needs-improvement":"poor";case "download":return e<=100?"good":e<=500?"needs-improvement":"poor";case "dom_processing":return e<=500?"good":e<=1500?"needs-improvement":"poor";case "page_load":return e<=1e3?"good":e<=3e3?"needs-improvement":"poor";default:return}}function ae(s){if(!s)return [];let e=[];for(let t of s.split(`
|
|
3
|
+
`)){let n=t.trim();if(!n||n.startsWith("Error")||n.startsWith("at Error"))continue;let r=/^at\s+(?:(.+?)\s+\()?(.+?):(\d+):(\d+)\)?$/.exec(n);if(r){let i=r[1]?.trim(),o=r[2];e.push({function:i&&i!=="<anonymous>"?i:void 0,filename:o,lineno:Number(r[3]),colno:Number(r[4]),abs_path:o,in_app:!o.includes("node_modules/")&&!o.includes("/dist/")&&!o.startsWith("internal/")});continue}if(r=/^([^@]*)@(.+?):(\d+):(\d+)$/.exec(n),r){let i=r[1]?.trim(),o=r[2];e.push({function:i||void 0,filename:o,lineno:Number(r[3]),colno:Number(r[4]),abs_path:o,in_app:!o.includes("node_modules/")&&!o.includes("/dist/")});}}return e}var T=class T{constructor(e){this.userProperties={};this.originalFetch=null;this.xhrPatched=false;this._debug=false;this.beforeSend=null;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.flagClient=null;if(this.apiKey=e.apiKey,this.endpoint=y(e.apiKey,e.endpoint,e.environment).replace(/\/+$/,""),this.flushInterval=e.flushInterval??J,this.batchSize=e.batchSize??z,this.defaultContext=e.defaultContext??{},this.onError=e.onError??(()=>{}),this.disabled=e.disabled??false,this.telemetry=e.telemetry??true,this.useEnvelope=e.useEnvelope??false,this.autoFetch=e.autoFetch??(this.useEnvelope&&e.autocapture!==false),this.release=e.release??null,this.environment=e.environment??"production",this._debug=e.debug??false,this.beforeSend=e.beforeSend??null,this.anonymousId=ne(),this.sessionId=re(),this._debug&&this._log("init",{endpoint:this.endpoint,sessionId:this.sessionId,distinctId:this.anonymousId,release:this.release,env:this.environment,envelope:this.useEnvelope,autoFetch:this.autoFetch}),this.disabled&&typeof console<"u"&&console.warn("[GoodLogs] SDK is disabled. No events or logs will be sent."),!this.disabled&&typeof setTimeout<"u"&&setTimeout(()=>{!this.release&&typeof console<"u"&&console.warn("[GoodLogs] No release version set. Set `release` in options or call gl.setRelease('1.2.3') for release health tracking.");},5e3),!this.disabled&&(this.startTimer(),this.attachPageLifecycle(),e.autocapture!==false&&(this.attachClickCapture(),this.captureWebVitals(),this.attachPageviewCapture(),this.attachGlobalErrorHandlers(),this.attachAutoBreadcrumbs()),this.autoFetch&&(this.attachFetchInstrumentation(),this.attachXhrInstrumentation()),this.sendTelemetry("init","info"),e.flags)){let t=typeof e.flags=="object"?e.flags:{};this.flagClient=new w(this.endpoint,this.apiKey,t.pollInterval??3e4),t.properties&&this.flagClient.setUser(this.anonymousId,t.properties),this.flagClient.start().catch(()=>{});}}log(e,t,n){if(this.disabled)return;let r=65536,i=t;t.length>r&&(i=t.slice(0,r-100)+`
|
|
4
4
|
|
|
5
|
-
[truncated \u2014 original ${t.length} chars, limit ${r}]`,this.onError(new Error(`Log message truncated from ${t.length} to ${r} chars`)));let
|
|
6
|
-
`);await this.postEnvelopeWithRetry(f,u);}}async postEnvelopeWithRetry(e,t,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:e});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(e,t,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 t)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 t)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(e,t,n,r=0){try{let s=await fetch(`${this.endpoint}${e}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,"X-GoodLogs-SDK":`js/${v}`},body:JSON.stringify({batch:t})});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(u=>setTimeout(u,d+a)),this.postWithRetry(e,t,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(t);return}let i=await s.json().catch(()=>null);if(i&&i.rejected&&i.rejected>0){let d=t.slice(i.accepted??0);d.length>0&&n(d);}}catch(s){let i=s instanceof Error?s:new Error(String(s));r===0&&n(t),this.onError(i);}}startTimer(){this.timer=setInterval(()=>{this.flush();},this.flushInterval);let e=this.timer;typeof e?.unref=="function"&&e.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 e=(t,n)=>{if(this.useEnvelope)this.captureVital(t.toLowerCase(),n);else {let r=t==="CLS"?"$value":"$value_ms";this.track("$web_vital",{properties:{$metric:t,[r]:t==="CLS"?n:Math.round(n)}});}};try{new PerformanceObserver(t=>{let n=t.getEntries()[0];n&&e("FCP",n.startTime);}).observe({type:"paint",buffered:!0});}catch{}try{new PerformanceObserver(t=>{let n=t.getEntries(),r=n[n.length-1];r&&e("LCP",r.startTime);}).observe({type:"largest-contentful-paint",buffered:!0});}catch{}try{let t=0;if(new PerformanceObserver(n=>{for(let r of n.getEntries())r.hadRecentInput||(t+=r.value);}).observe({type:"layout-shift",buffered:!0}),typeof document<"u"){let n=()=>{t>0&&e("CLS",Math.round(t*1e3)/1e3);};document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&n();});}}catch{}try{new PerformanceObserver(t=>{for(let n of t.getEntries()){let r=n;r.responseStart&&r.responseStart>0&&e("TTFB",r.responseStart);let s=c=>c&&Number.isFinite(c)&&c>0?c:0,i=s(r.domainLookupEnd)-s(r.domainLookupStart);i>0&&this.captureVital("dns",i);let d=s(r.connectEnd)-s(r.connectStart);d>0&&this.captureVital("tcp",d);let a=s(r.responseEnd)-s(r.responseStart);a>0&&this.captureVital("download",a);let u=s(r.domComplete)-s(r.responseEnd);u>0&&this.captureVital("dom_processing",u);let l=s(r.loadEventEnd)-s(r.fetchStart);l>0&&this.captureVital("page_load",l);}}).observe({type:"navigation",buffered:!0});}catch{try{if(typeof performance<"u"){let t=performance.getEntriesByType?.("navigation")?.[0];t?.responseStart&&e("TTFB",t.responseStart);let n=u=>u&&Number.isFinite(u)&&u>0?u:0,r=n(t?.domainLookupEnd)-n(t?.domainLookupStart);r>0&&this.captureVital("dns",r);let s=n(t?.connectEnd)-n(t?.connectStart);s>0&&this.captureVital("tcp",s);let i=n(t?.responseEnd)-n(t?.responseStart);i>0&&this.captureVital("download",i);let d=n(t?.domComplete)-n(t?.responseEnd);d>0&&this.captureVital("dom_processing",d);let a=n(t?.loadEventEnd)-n(t?.fetchStart);a>0&&this.captureVital("page_load",a);}}catch{}}try{new PerformanceObserver(t=>{for(let n of t.getEntries()){let r=n.duration;r>0&&e("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 e=(t="push")=>{typeof location<"u"&&location.pathname!==this.lastPath&&(this.lastPath=location.pathname,this.track("$pageview"),this.startNavTransaction(this.lastPath,t));};if(typeof history<"u"){let t=history.pushState,n=history.replaceState;history.pushState=function(...r){t.apply(this,r),e("push");},history.replaceState=function(...r){n.apply(this,r),e("replace");};}typeof addEventListener<"u"&&addEventListener("popstate",()=>e("popstate"));}startNavTransaction(e,t){try{this.navTransaction&&(this.navTransaction.finish(),this.navTransaction=null),this.navTransaction=this.startTransaction({op:"navigation",name:e,attributes:{"navigation.type":t,"http.url":typeof location<"u"?location.href:e}});let n=this.navTransaction;setTimeout(()=>{this.navTransaction===n&&(n.finish(),this.navTransaction=null);},3e4);}catch{}}attachGlobalErrorHandlers(){let e=globalThis;typeof e.addEventListener=="function"&&(this.errorHandler||this.rejectionHandler||(this.errorHandler=t=>{let n=t,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=t=>{let r=t.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{}},e.addEventListener("error",this.errorHandler),e.addEventListener("unhandledrejection",this.rejectionHandler)));}detachGlobalErrorHandlers(){let e=globalThis;typeof e.removeEventListener=="function"&&(this.errorHandler&&(e.removeEventListener("error",this.errorHandler),this.errorHandler=null),this.rejectionHandler&&(e.removeEventListener("unhandledrejection",this.rejectionHandler),this.rejectionHandler=null));}attachAutoBreadcrumbs(){if(typeof console<"u"){let e=this,t=["error","warn","info","log"];for(let n of t){let r=console[n];r&&(console[n]=function(...s){try{e.addBreadcrumb({category:"console",message:s.map(i=>typeof i=="string"?i:JSON.stringify(i)).join(" ").slice(0,500),level:n==="error"?"error":n==="warn"?"warning":"info"});}catch{}return r.apply(console,s)});}}if(typeof globalThis<"u"&&typeof globalThis.history<"u"){let e=this,t=globalThis,n=t.history.pushState;t.history.pushState=function(...r){try{e.addBreadcrumb({category:"navigation",message:`\u2192 ${String(r[2]??"")}`,level:"info"});}catch{}return n.apply(t.history,r)},t.addEventListener("popstate",()=>{try{e.addBreadcrumb({category:"navigation",message:`\u2190 ${t.location.pathname}`,level:"info"});}catch{}});}}attachFetchInstrumentation(){if(typeof fetch>"u")return;let e=globalThis;if(this.originalFetch)return;this.originalFetch=e.fetch;let t=e.fetch.bind(globalThis),n=this;e.fetch=function(s,i){let d="",a="GET";if(typeof s=="string")d=s;else if(s&&typeof s=="object"){let c=s;d=c.url??"",a=c.method??a;}let u=i??{};if(u.method?a=String(u.method).toUpperCase():typeof s=="object"&&(a=s.method?.toUpperCase()??a),d.startsWith(n.endpoint))return t(s,u);let l=n.startSpan({op:"http.client",name:`${a} ${d}`,attributes:{"http.method":a,"http.url":d},parent:n.navTransaction??void 0});try{let c=`00-${l.trace_id}-${l.span_id}-01`,f={...u},g=f.headers??{};return f.headers={...g,traceparent:c},t(s,f).then(h=>{let p=h;return typeof p.status=="number"&&l.setAttribute("http.status_code",p.status),l.setStatus(p.ok===!1?"error":"ok"),l.finish(),h}).catch(h=>{throw l.setStatus("error"),l.setAttribute("error.message",h instanceof Error?h.message:String(h)),l.finish(),h})}catch(c){throw l.setStatus("error"),l.finish(),c}};}detachFetchInstrumentation(){this.originalFetch&&(globalThis.fetch=this.originalFetch,this.originalFetch=null);}attachXhrInstrumentation(){let t=globalThis.XMLHttpRequest;if(!t||!t.prototype)return;let n=Symbol.for("goodlogs.xhr.patched"),r=t.prototype;if(r[n]){this.xhrPatched=true;return}let s=r.open,i=r.setRequestHeader,d=r.send,a=this;r.open=function(l,c,...f){return this.__gl_method=typeof l=="string"?l.toUpperCase():"GET",this.__gl_url=typeof c=="string"?c:String(c??""),this.__gl_headers_set=false,s.apply(this,[l,c,...f])},r.setRequestHeader=function(l,c){return this.__gl_headers_set=true,i.apply(this,[l,c])},r.send=function(l){let c=this.__gl_url||"",f=this.__gl_method||"GET";if(c.startsWith(a.endpoint))return d.apply(this,[l]);let g=a.startSpan({op:"http.client",name:`${f} ${c}`,attributes:{"http.method":f,"http.url":c},parent:a.navTransaction??void 0});try{let m=`00-${g.trace_id}-${g.span_id}-01`;i.apply(this,["traceparent",m]);}catch{}let h=(m,_,N)=>{m&&g.setAttribute("http.status_code",m),N&&g.setAttribute("error.message",N),g.setStatus(_?"ok":"error"),g.finish();},p=this.addEventListener;return typeof p=="function"?(p.call(this,"load",()=>{let m=Number(this.status||0);h(m,m>0&&m<500);}),p.call(this,"error",()=>h(0,false,"network error")),p.call(this,"abort",()=>h(0,false,"aborted")),p.call(this,"timeout",()=>h(0,false,"timeout"))):h(0,true),d.apply(this,[l])},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 t=globalThis.XMLHttpRequest?.prototype;if(!t)return;let n=Symbol.for("goodlogs.xhr.patched");t.__gl_orig_open&&(t.open=t.__gl_orig_open),t.__gl_orig_set_header&&(t.setRequestHeader=t.__gl_orig_set_header),t.__gl_orig_send&&(t.send=t.__gl_orig_send),delete t.__gl_orig_open,delete t.__gl_orig_set_header,delete t.__gl_orig_send,delete t[n],this.xhrPatched=false;}attachClickCapture(){typeof document>"u"||(this.clickHandler=e=>{let t=e,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),u=globalThis,l=u.innerWidth,c=u.innerHeight,f=u.scrollY,g=typeof document<"u"?document.documentElement?.scrollHeight:void 0;this.track(r||"$click",{$element_tag:s,$element_id:n.id||void 0,$element_text:i||void 0,$element_href:d,$element_classes:a||void 0,$element_selector:X(n),$click_x:t.clientX,$click_y:t.clientY,$page_x:t.pageX,$page_y:t.pageY,$viewport_w:l,$viewport_h:c,$scroll_y:f,$doc_h:g,$url:typeof location<"u"?location.href:void 0,$pathname:typeof location<"u"?location.pathname: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 e=this.logBuffer.splice(0),t=this.eventBuffer.splice(0),n={"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,"X-GoodLogs-SDK":`js/${v}`};e.length>0&&fetch(`${this.endpoint}/v1/logs`,{method:"POST",headers:n,body:JSON.stringify({batch:e.map(r=>({severity:r.severity,message:r.message,properties:r.properties,timestamp:r.timestamp}))}),keepalive:true}).catch(()=>{}),t.length>0&&fetch(`${this.endpoint}/v1/events`,{method:"POST",headers:n,body:JSON.stringify({batch:t.map(r=>({event:r.event,distinctId:r.distinctId,properties:r.properties,timestamp:r.timestamp}))}),keepalive:true}).catch(()=>{});}sendTelemetry(e,t,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:e,level:t,metadata:{...n,sdk_version:v}}),keepalive:true}).catch(()=>{});}};R.MAX_BREADCRUMBS=50;var I=R;var C=class{constructor(e){if(!e.apiKey)throw new Error("apiKey is required");if(!e.apiKey.startsWith("gl_sk_"))throw new Error("GoodLogsClient requires a secret API key (gl_sk_...)");this.apiKey=e.apiKey,this.endpoint=y(e.apiKey,e.endpoint),this.timeout=e.timeout??3e4,this.alerts=new x(this),this.slos=new L(this),this.ai=new P(this);}async _request(e,t,n){let r=`${this.endpoint}${t}`,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:e,headers:s,body:n?JSON.stringify(n):void 0,signal:i.signal});if(!a.ok){let u=await a.json().catch(()=>({})),l=u?.error?.message??`API error ${a.status}`;throw new T(a.status,l,u?.error?.code)}return a.status===204?void 0:await a.json()}finally{clearTimeout(d);}}_get(e){return this._request("GET",e)}_post(e,t){return this._request("POST",e,t)}_put(e,t){return this._request("PUT",e,t)}_delete(e){return this._request("DELETE",e)}info(){return this._get("/v1/info")}schema(){return this._get("/v1/schema")}gql(e){return this._post("/v1/gql/query",{q:e})}gqlBatch(e){return this._post("/v1/gql",{queries:e})}gqlAutocomplete(e,t){let n=`/v1/gql/autocomplete?q=${encodeURIComponent(e)}`;return t!==void 0&&(n+=`&cursor=${t}`),this._get(n)}nl2gql(e,t){return this._post("/v1/gql/nl",{prompt:e,mode:t})}},x=class{constructor(e){this.client=e;}list(){return this.client._get("/v1/alerts")}create(e){return this.client._post("/v1/alerts",e)}update(e,t){return this.client._put(`/v1/alerts/${e}`,t)}delete(e){return this.client._delete(`/v1/alerts/${e}`)}mute(e,t){return this.client._post(`/v1/alerts/${e}/mute`,{minutes:t})}},L=class{constructor(e){this.client=e;}list(){return this.client._get("/v1/slos")}create(e){return this.client._post("/v1/slos",e)}update(e,t){return this.client._put(`/v1/slos/${e}`,t)}delete(e){return this.client._delete(`/v1/slos/${e}`)}},P=class{constructor(e){this.client=e;}chat(e,t){return this.client._post("/v1/ai/chat",{message:e,session_id:t})}},T=class extends Error{constructor(t,n,r){super(n);this.status=t;this.code=r;this.name="GoodLogsApiError";}};var O="0.1.0";function Z(o,e){let t=y(e?.apiKey??"",e?.endpoint).replace(/\/+$/,""),n={"Content-Type":"application/json","X-GoodLogs-SDK":O};e?.token&&(n.Authorization=`Bearer ${e.token}`),fetch(`${t}/v1/telemetry`,{method:"POST",headers:n,body:JSON.stringify({source:o.source,event:o.event,level:o.level??"info",metadata:{...o.metadata,sdk_version:O}}),keepalive:true}).catch(()=>{});}function $(o){if(!o)return null;let e=o.trim().split("-");if(e.length!==4)return null;let[t,n,r,s]=e;return t.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 A(o,e){if(!o)return;let t=o[e]??o[e.toLowerCase()];return Array.isArray(t)?t[0]:t}function ee(o){return function(t,n,r){let s=(t.method??"GET").toUpperCase(),i=t.originalUrl??t.url??"",d=$(A(t.headers,"traceparent")),a=o.startTransaction({op:"http.server",name:`${s} ${i}`,trace_id:d?.trace_id,attributes:{"http.method":s,"http.url":i}}),u=false,l=()=>{if(u)return;u=true;let c=t.route?.path;c&&a.setAttribute("http.route",c);let f=n.statusCode??200;a.setAttribute("http.status_code",f),a.setStatus(f>=500?"error":"ok"),a.finish();};n.on("finish",l),n.on("close",l),t.goodlogs={span:a},r();}}function te(o){return function(t,n,r){t.addHook("onRequest",(s,i,d)=>{let a=(s.method??"GET").toUpperCase(),u=s.url??"",l=$(A(s.headers,"traceparent")),c=o.startTransaction({op:"http.server",name:`${a} ${u}`,trace_id:l?.trace_id,attributes:{"http.method":a,"http.url":u}});s.__goodlogsSpan=c,d();}),t.addHook("onResponse",(s,i,d)=>{let a=s.__goodlogsSpan;if(a){let u=s.routerPath??s.routeOptions?.url;u&&a.setAttribute("http.route",u);let l=i.statusCode??i.raw?.statusCode??200;a.setAttribute("http.status_code",l),a.setStatus(l>=500?"error":"ok"),a.finish();}d();}),r();}}function ne(o){return {intercept(e,t){let n=e.switchToHttp(),r=n.getRequest(),s=n.getResponse(),i=(r.method??"GET").toUpperCase(),d=r.originalUrl??r.url??"",a=$(A(r.headers,"traceparent")),u=o.startTransaction({op:"http.server",name:`${i} ${d}`,trace_id:a?.trace_id,attributes:{"http.method":i,"http.url":d}}),l=false,c=(g,h)=>{if(l)return;l=true;let p=r.route?.path;p&&u.setAttribute("http.route",p);let m=g??s.statusCode??200;u.setAttribute("http.status_code",m),u.setStatus(h||m>=500?"error":"ok"),u.finish();};s.on("finish",()=>c()),s.on("close",()=>c());let f=t.handle();if(f&&typeof f.subscribe=="function"){let g=f.subscribe({next:()=>{},error:h=>{u.setAttribute("error.message",h instanceof Error?h.message:String(h)),c(500,true);},complete:()=>c()});return {unsubscribe:()=>g.unsubscribe?.()}}return f}}}function re(o){let e=globalThis.process;if(!e||typeof e.on!="function")return;let t=e,n=Symbol.for("goodlogs.node-process.patched");t[n]||(e.on("uncaughtException",r=>{try{o.captureException(r instanceof Error?r:new Error(String(r)),{tags:{source:"uncaughtException"},level:"fatal"}),o.flush();}catch{}}),e.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{}}),t[n]=true);}var H=globalThis.URL;function E(o){return !!H&&o instanceof H}var q=Symbol.for("goodlogs.node-http.patched");function se(...o){let e=o[0],t=o[1],n="GET",r="";if(typeof e=="string")r=e,t&&typeof t=="object"&&!E(t)&&(n=String(t.method??n).toUpperCase());else if(E(e))r=e.toString(),t&&typeof t=="object"&&!E(t)&&(n=String(t.method??n).toUpperCase());else if(e&&typeof e=="object"){let i=e;n=String(i.method??n).toUpperCase();let d=(i.protocol??"http:").replace(":",""),a=i.hostname??i.host??"localhost",u=i.port?`:${i.port}`:"";r=`${d}://${a}${u}${i.path??"/"}`;}return {method:n,url:r,isOurs:i=>!!i&&r.startsWith(i)}}function ie(o,e,t){let n=o[0]&&typeof o[0]=="object"&&!E(o[0])?o[0]:o[1]&&typeof o[1]=="object"&&!E(o[1])?o[1]:void 0;n&&(n.headers||(n.headers={}),!(e in n.headers)&&!(e.toLowerCase()in n.headers)&&(n.headers[e]=t));}function oe(o,e){let t=e?.endpoint??o.endpoint??"",n=r=>{let s=r;if(s[q])return;s[q]=true;let i=r.request.bind(r);r.request=function(...a){let{method:u,url:l,isOurs:c}=se(...a);if(!l||c(t))return i(...a);let f=o.startTransaction({op:"http.client",name:`${u} ${l}`,attributes:{"http.method":u,"http.url":l}});ie(a,"traceparent",`00-${f.trace_id}-${f.span_id}-01`);let g=false,h=(m,_)=>{g||(g=true,typeof m=="number"&&f.setAttribute("http.status_code",m),_?(f.setAttribute("error.message",_.message),f.setStatus("error")):f.setStatus(typeof m=="number"&&m>=500?"error":"ok"),f.finish());},p=i(...a);return p.on("response",m=>h(m.statusCode)),p.on("error",m=>h(void 0,m)),p.on("close",()=>h()),p};};if(typeof w=="function"){try{let r=w("http");n(r);}catch{}try{let r=w("https");n(r);}catch{}}}
|
|
7
|
-
exports.GoodLogs=
|
|
5
|
+
[truncated \u2014 original ${t.length} chars, limit ${r}]`,this.onError(new Error(`Log message truncated from ${t.length} to ${r} chars`)));let o=ee(),a={severity:e,message:i,properties:{...this.defaultContext,...Z(this.sessionId,this.anonymousId,this.release,this.environment,this.userProperties),...o?{code_location:o}:{},...n},timestamp:new Date().toISOString()};this.logBuffer.push(a),this.logBuffer.length>=this.batchSize&&this.flush();}debug(e,t){this.log("debug",e,t);}info(e,t){this.log("info",e,t);}warn(e,t){this.log("warn",e,t);}error(e,t){this.log("error",e,t);}fatal(e,t){this.log("fatal",e,t);}identify(e){this.anonymousId=e,typeof localStorage<"u"&&localStorage.setItem($,e);}getDistinctId(){return this.anonymousId}reset(){this.anonymousId=b(),this.sessionId=b(),typeof localStorage<"u"&&localStorage.setItem($,this.anonymousId),typeof sessionStorage<"u"&&sessionStorage.setItem(_,this.sessionId);}getSessionId(){return this.sessionId}newSession(){this.sessionId=b(),typeof sessionStorage<"u"&&sessionStorage.setItem(_,this.sessionId),this._debug&&this._log("newSession",{sessionId:this.sessionId});}_log(e,t){if(!this._debug||typeof console>"u")return;let n=new Date().toISOString().slice(11,23);t?console.log(`%c[GL ${n}]%c ${e}`,"color:#10b981;font-weight:bold","color:inherit",t):console.log(`%c[GL ${n}]%c ${e}`,"color:#10b981;font-weight:bold","color:inherit");}setSessionId(e){this.sessionId=e,typeof sessionStorage<"u"&&sessionStorage.setItem(_,e);}setRelease(e){this.release=e;}getRelease(){return this.release}setEnvironment(e){this.environment=e;}getEnvironment(){return this.environment}setUser(e){this.identify(e.id),this.userProperties={...e},this.flagClient&&this.flagClient.setUser(e.id,this.userProperties);}getUser(){return {...this.userProperties}}isEnabled(e,t=false,n){return this.flagClient?this.flagClient.isEnabled(e,t,n):t}getVariant(e,t,n){return this.flagClient?this.flagClient.getVariant(e,t,n):t}getAllFlags(){return this.flagClient?this.flagClient.getAllFlags():{}}onFlagChange(e,t){return this.flagClient?this.flagClient.onFlagChange(e,t):()=>{}}flagsReady(){return this.flagClient?this.flagClient.onReady():Promise.resolve()}track(e,t){if(this.disabled)return;let{distinctId:n,...r}=t??{},i={event:e,distinctId:n??this.anonymousId,properties:{...Y(),...r,$session_id:this.sessionId,...this.release?{$release:this.release}:{},$environment:this.environment},timestamp:new Date().toISOString()};this.eventBuffer.push(i),this._debug&&this._log("track",{event:e,sessionId:this.sessionId}),this.eventBuffer.length>=this.batchSize&&this.flush();}addBreadcrumb(e){if(this.disabled)return;let t={ts:e.ts??new Date().toISOString(),...e};this.breadcrumbBuffer.push(t),this.breadcrumbBuffer.length>T.MAX_BREADCRUMBS&&this.breadcrumbBuffer.shift();}captureException(e,t){if(this.disabled)return;let n=this.buildErrorEntry(e,t);if(this.beforeSend){try{n=this.beforeSend(n);}catch{n=null;}if(!n)return}this._debug&&this._log("captureException",{message:n.message,type:n.exception_type,sessionId:this.sessionId,traceId:n.trace_id}),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(e,t){if(this.disabled)return;let n={level:t?.level??"info",message:e,platform:typeof document<"u"?"browser":"node",frames:[],breadcrumbs:this.breadcrumbBuffer.slice(),fingerprint:t?.fingerprint,tags:{session_id:this.sessionId,...t?.tags},extra:t?.extra,user_id:t?.user_id??this.anonymousId,timestamp:new Date().toISOString()};this.useEnvelope?(this.errorBuffer.push(n),this.errorBuffer.length>=this.batchSize&&this.flush()):this.warn(e);}buildErrorEntry(e,t){let n,r,i=[];if(e instanceof Error)n=e.name,r=e.message,i=ae(e.stack);else if(typeof e=="string")r=e;else try{r=JSON.stringify(e);}catch{r=String(e);}return {level:t?.level??"error",platform:typeof document<"u"?"browser":"node",exception_type:n,message:r,frames:i,breadcrumbs:this.breadcrumbBuffer.slice(),fingerprint:t?.fingerprint,tags:{session_id:this.sessionId,...t?.tags},extra:t?.extra,user_id:t?.user_id??this.anonymousId,timestamp:new Date().toISOString(),trace_id:this.navTransaction?.trace_id,span_id:this.navTransaction?.span_id,release:this.release??void 0,environment:this.environment}}captureVital(e,t,n){if(this.disabled||!Number.isFinite(t)||t<0)return;let r=n?.rating??oe(e,t),i={metric:e,value_ms:e==="cls"?t:Math.round(t),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(i),this.vitalBuffer.length>=this.batchSize&&this.flush()):this.track("$web_vital",{properties:{$metric:e.toUpperCase(),$value_ms:i.value_ms,$rating:r}});}startTransaction(e){return this.makeSpan(void 0,e)}startSpan(e){return this.makeSpan(void 0,e)}makeSpan(e,t){let n=t?.trace_id??t?.parent?.trace_id??e?.trace_id??ie(),r=se(),i=t?.parent?.span_id??e?.span_id,o=Date.now(),a=new Date(o).toISOString(),l={...t?.attributes??{}},u="unset",d=[],c=false,f=this,g={span_id:r,trace_id:n,setAttribute(h,p){l[h]=p;},setStatus(h){u=h;},addEvent(h,p){d.push({ts:new Date().toISOString(),name:h,attributes:p});},startChild(h){return f.makeSpan(g,h)},finish(){if(c)return;c=true;let h=Date.now(),p={span_id:r,trace_id:n,parent_span_id:i,name:t?.name,op:t?.op,status:u==="unset"?"ok":u,kind:t?.kind,attributes:l,events:d,start_time:a,end_time:new Date(h).toISOString(),timestamp:a,duration_ms:h-o};f.useEnvelope&&(f.spanBuffer.push(p),f.spanBuffer.length>=f.batchSize&&f.flush());}};return g}async flush(){let e=this.logBuffer.splice(0),t=this.eventBuffer.splice(0),n=this.errorBuffer.splice(0),r=this.vitalBuffer.splice(0),i=this.spanBuffer.splice(0);this._debug&&(e.length||t.length||n.length||r.length||i.length)&&this._log("flush",{logs:e.length,events:t.length,errors:n.length,vitals:r.length,spans:i.length});let o=[];this.useEnvelope?(e.length>0||t.length>0||n.length>0||r.length>0||i.length>0)&&o.push(this.sendEnvelope(e,t,n,r,i)):(e.length>0&&o.push(this.sendLogs(e)),t.length>0&&o.push(this.sendEvents(t))),await Promise.all(o);}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(e){for(let n=0;n<e.length;n+=500){let i=e.slice(n,n+500).map(o=>({severity:o.severity,message:o.message,properties:o.properties,timestamp:o.timestamp}));await this.postWithRetry("/v1/logs",i,o=>{for(let a of o)this.logBuffer.push({severity:a.severity,message:a.message,properties:a.properties,timestamp:a.timestamp});});}}async sendEvents(e){for(let n=0;n<e.length;n+=500){let i=e.slice(n,n+500).map(o=>({event:o.event,distinctId:o.distinctId,properties:o.properties,timestamp:o.timestamp}));await this.postWithRetry("/v1/events",i,o=>{for(let a of o)this.eventBuffer.push({event:a.event,distinctId:a.distinctId,properties:a.properties,timestamp:a.timestamp});});}}async sendEnvelope(e,t,n,r,i){let a=[...e.map(l=>({kind:"log",entry:l})),...t.map(l=>({kind:"event",entry:l})),...n.map(l=>({kind:"error",entry:l})),...r.map(l=>({kind:"vital",entry:l})),...i.map(l=>({kind:"span",entry:l}))];for(let l=0;l<a.length;l+=1e3){let u=a.slice(l,l+1e3),d=JSON.stringify({v:1,sdk:`js@${v}`,sent_at:new Date().toISOString()}),c=u.map(g=>{if(g.kind==="log"){let p=g.entry;return JSON.stringify({type:"log",severity:p.severity,message:p.message,properties:p.properties,timestamp:p.timestamp})}if(g.kind==="event"){let p=g.entry;return JSON.stringify({type:"event",event:p.event,distinctId:p.distinctId,properties:p.properties,timestamp:p.timestamp})}if(g.kind==="error"){let p=g.entry;return JSON.stringify({type:"error",...p})}if(g.kind==="vital"){let p=g.entry;return JSON.stringify({type:"vital",...p})}let h=g.entry;return JSON.stringify({type:"span",...h})}),f=[d,...c].join(`
|
|
6
|
+
`);await this.postEnvelopeWithRetry(f,u);}}async postEnvelopeWithRetry(e,t,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:e});if(r.status===429||r.status===503){if(n<4){let i=Math.min(1e3*Math.pow(2,n),8e3),o=Math.random()*500;return await new Promise(a=>setTimeout(a,i+o)),this.postEnvelopeWithRetry(e,t,n+1)}this.onError(new Error(`GoodLogs rate limited after ${n} retries`));return}if(!r.ok){let i=await r.text().catch(()=>"");if(this.onError(new Error(`GoodLogs envelope error ${r.status}: ${i}`)),r.status>=500&&n===0)for(let o of t)o.kind==="log"?this.logBuffer.push(o.entry):o.kind==="event"?this.eventBuffer.push(o.entry):o.kind==="error"?this.errorBuffer.push(o.entry):o.kind==="vital"?this.vitalBuffer.push(o.entry):this.spanBuffer.push(o.entry);}}catch(r){if(n===0)for(let i of t)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);this.onError(r instanceof Error?r:new Error(String(r)));}}async postWithRetry(e,t,n,r=0){try{let i=await fetch(`${this.endpoint}${e}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,"X-GoodLogs-SDK":`js/${v}`},body:JSON.stringify({batch:t})});if(i.status===429||i.status===503){if(r<4){let a=Math.min(1e3*Math.pow(2,r),8e3),l=Math.random()*500;return await new Promise(u=>setTimeout(u,a+l)),this.postWithRetry(e,t,n,r+1)}this.onError(new Error(`GoodLogs rate limited after ${r} retries`));return}if(!i.ok){let a=await i.text().catch(()=>""),l=new Error(`GoodLogs API error ${i.status}: ${a}`);this.onError(l),i.status>=500&&r===0&&n(t);return}let o=await i.json().catch(()=>null);if(o&&o.rejected&&o.rejected>0){let a=t.slice(o.accepted??0);a.length>0&&n(a);}}catch(i){let o=i instanceof Error?i:new Error(String(i));r===0&&n(t),this.onError(o);}}startTimer(){this.timer=setInterval(()=>{this.flush();},this.flushInterval);let e=this.timer;typeof e?.unref=="function"&&e.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 e=(t,n)=>{if(this.useEnvelope)this.captureVital(t.toLowerCase(),n);else {let r=t==="CLS"?"$value":"$value_ms";this.track("$web_vital",{properties:{$metric:t,[r]:t==="CLS"?n:Math.round(n)}});}};try{new PerformanceObserver(t=>{let n=t.getEntries()[0];n&&e("FCP",n.startTime);}).observe({type:"paint",buffered:!0});}catch{}try{new PerformanceObserver(t=>{let n=t.getEntries(),r=n[n.length-1];r&&e("LCP",r.startTime);}).observe({type:"largest-contentful-paint",buffered:!0});}catch{}try{let t=0;if(new PerformanceObserver(n=>{for(let r of n.getEntries())r.hadRecentInput||(t+=r.value);}).observe({type:"layout-shift",buffered:!0}),typeof document<"u"){let n=()=>{t>0&&e("CLS",Math.round(t*1e3)/1e3);};document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&n();});}}catch{}try{new PerformanceObserver(t=>{for(let n of t.getEntries()){let r=n;r.responseStart&&r.responseStart>0&&e("TTFB",r.responseStart);let i=c=>c&&Number.isFinite(c)&&c>0?c:0,o=i(r.domainLookupEnd)-i(r.domainLookupStart);o>0&&this.captureVital("dns",o);let a=i(r.connectEnd)-i(r.connectStart);a>0&&this.captureVital("tcp",a);let l=i(r.responseEnd)-i(r.responseStart);l>0&&this.captureVital("download",l);let u=i(r.domComplete)-i(r.responseEnd);u>0&&this.captureVital("dom_processing",u);let d=i(r.loadEventEnd)-i(r.fetchStart);d>0&&this.captureVital("page_load",d);}}).observe({type:"navigation",buffered:!0});}catch{try{if(typeof performance<"u"){let t=performance.getEntriesByType?.("navigation")?.[0];t?.responseStart&&e("TTFB",t.responseStart);let n=u=>u&&Number.isFinite(u)&&u>0?u:0,r=n(t?.domainLookupEnd)-n(t?.domainLookupStart);r>0&&this.captureVital("dns",r);let i=n(t?.connectEnd)-n(t?.connectStart);i>0&&this.captureVital("tcp",i);let o=n(t?.responseEnd)-n(t?.responseStart);o>0&&this.captureVital("download",o);let a=n(t?.domComplete)-n(t?.responseEnd);a>0&&this.captureVital("dom_processing",a);let l=n(t?.loadEventEnd)-n(t?.fetchStart);l>0&&this.captureVital("page_load",l);}}catch{}}try{new PerformanceObserver(t=>{for(let n of t.getEntries()){let r=n.duration;r>0&&e("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 e=(t="push")=>{typeof location<"u"&&location.pathname!==this.lastPath&&(this.lastPath=location.pathname,this.track("$pageview"),this.startNavTransaction(this.lastPath,t));};if(typeof history<"u"){let t=history.pushState,n=history.replaceState;history.pushState=function(...r){t.apply(this,r),e("push");},history.replaceState=function(...r){n.apply(this,r),e("replace");};}if(typeof addEventListener<"u"&&addEventListener("popstate",()=>e("popstate")),typeof document<"u"){let t=0,n=0,r=null;document.addEventListener("click",i=>{let a=i?.target;if(!a)return;let l=Date.now(),u=`${(a.tagName??"unknown").toLowerCase()}${a.id?"#"+a.id:""}${a.className&&typeof a.className=="string"?"."+a.className.trim().split(/\s+/).slice(0,2).join("."):""}`.slice(0,100);if(r===a&&l-t<1e3?(n++,n===3&&this.track("$rage_click",{$element:u,$tag:(a.tagName??"").toLowerCase(),$text:(a.textContent??"").slice(0,50).trim(),$url:typeof location<"u"?location.pathname:void 0})):n=1,r=a,t=l,!a.closest?.("a, button, input, select, textarea, [role=button], [onclick]")){let c=typeof location<"u"?location.pathname:"";setTimeout(()=>{(typeof location<"u"?location.pathname:"")===c&&this.track("$dead_click",{$element:u,$tag:(a.tagName??"").toLowerCase(),$text:(a.textContent??"").slice(0,50).trim(),$url:typeof location<"u"?location.pathname:void 0});},500);}},{capture:true,passive:true});}}startNavTransaction(e,t){try{this.navTransaction&&(this.navTransaction.finish(),this.navTransaction=null),this.navTransaction=this.startTransaction({op:"navigation",name:e,attributes:{"navigation.type":t,"http.url":typeof location<"u"?location.href:e}});let n=this.navTransaction;setTimeout(()=>{this.navTransaction===n&&(n.finish(),this.navTransaction=null);},3e4);}catch{}}attachGlobalErrorHandlers(){let e=globalThis;typeof e.addEventListener=="function"&&(this.errorHandler||this.rejectionHandler||(this.errorHandler=t=>{let n=t,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=t=>{let r=t.reason,i=r;if(!(r instanceof Error)){let o;if(typeof r=="string")o=r;else try{o=JSON.stringify(r);}catch{o=String(r);}i=new Error(o);}try{this.captureException(i,{tags:{source:"unhandledrejection"}});}catch{}},e.addEventListener("error",this.errorHandler),e.addEventListener("unhandledrejection",this.rejectionHandler)));}detachGlobalErrorHandlers(){let e=globalThis;typeof e.removeEventListener=="function"&&(this.errorHandler&&(e.removeEventListener("error",this.errorHandler),this.errorHandler=null),this.rejectionHandler&&(e.removeEventListener("unhandledrejection",this.rejectionHandler),this.rejectionHandler=null));}attachAutoBreadcrumbs(){if(typeof console<"u"){let e=this,t=["error","warn","info","log"];for(let n of t){let r=console[n];r&&(console[n]=function(...i){try{e.addBreadcrumb({category:"console",message:i.map(o=>typeof o=="string"?o:JSON.stringify(o)).join(" ").slice(0,500),level:n==="error"?"error":n==="warn"?"warning":"info"});}catch{}return r.apply(console,i)});}}if(typeof globalThis<"u"&&typeof globalThis.history<"u"){let e=this,t=globalThis,n=t.history.pushState;t.history.pushState=function(...r){try{e.addBreadcrumb({category:"navigation",message:`\u2192 ${String(r[2]??"")}`,level:"info"});}catch{}return n.apply(t.history,r)},t.addEventListener("popstate",()=>{try{e.addBreadcrumb({category:"navigation",message:`\u2190 ${t.location.pathname}`,level:"info"});}catch{}});}}attachFetchInstrumentation(){if(typeof fetch>"u")return;let e=globalThis;if(this.originalFetch)return;this.originalFetch=e.fetch;let t=e.fetch.bind(globalThis),n=this;e.fetch=function(i,o){let a="",l="GET";if(typeof i=="string")a=i;else if(i&&typeof i=="object"){let c=i;a=c.url??"",l=c.method??l;}let u=o??{};if(u.method?l=String(u.method).toUpperCase():typeof i=="object"&&(l=i.method?.toUpperCase()??l),a.startsWith(n.endpoint))return t(i,u);let d=n.startSpan({op:"http.client",name:`${l} ${a}`,attributes:{"http.method":l,"http.url":a},parent:n.navTransaction??void 0});try{let c=`00-${d.trace_id}-${d.span_id}-01`,f={...u},g=f.headers??{};return f.headers={...g,traceparent:c},t(i,f).then(h=>{let p=h;return typeof p.status=="number"&&d.setAttribute("http.status_code",p.status),d.setStatus(p.ok===!1?"error":"ok"),d.finish(),h}).catch(h=>{throw d.setStatus("error"),d.setAttribute("error.message",h instanceof Error?h.message:String(h)),d.finish(),h})}catch(c){throw d.setStatus("error"),d.finish(),c}};}detachFetchInstrumentation(){this.originalFetch&&(globalThis.fetch=this.originalFetch,this.originalFetch=null);}attachXhrInstrumentation(){let t=globalThis.XMLHttpRequest;if(!t||!t.prototype)return;let n=Symbol.for("goodlogs.xhr.patched"),r=t.prototype;if(r[n]){this.xhrPatched=true;return}let i=r.open,o=r.setRequestHeader,a=r.send,l=this;r.open=function(d,c,...f){return this.__gl_method=typeof d=="string"?d.toUpperCase():"GET",this.__gl_url=typeof c=="string"?c:String(c??""),this.__gl_headers_set=false,i.apply(this,[d,c,...f])},r.setRequestHeader=function(d,c){return this.__gl_headers_set=true,o.apply(this,[d,c])},r.send=function(d){let c=this.__gl_url||"",f=this.__gl_method||"GET";if(c.startsWith(l.endpoint))return a.apply(this,[d]);let g=l.startSpan({op:"http.client",name:`${f} ${c}`,attributes:{"http.method":f,"http.url":c},parent:l.navTransaction??void 0});try{let m=`00-${g.trace_id}-${g.span_id}-01`;o.apply(this,["traceparent",m]);}catch{}let h=(m,S,F)=>{m&&g.setAttribute("http.status_code",m),F&&g.setAttribute("error.message",F),g.setStatus(S?"ok":"error"),g.finish();},p=this.addEventListener;return typeof p=="function"?(p.call(this,"load",()=>{let m=Number(this.status||0);h(m,m>0&&m<500);}),p.call(this,"error",()=>h(0,false,"network error")),p.call(this,"abort",()=>h(0,false,"aborted")),p.call(this,"timeout",()=>h(0,false,"timeout"))):h(0,true),a.apply(this,[d])},r[n]=true,r.__gl_orig_open=i,r.__gl_orig_set_header=o,r.__gl_orig_send=a,this.xhrPatched=true;}detachXhrInstrumentation(){if(!this.xhrPatched)return;let t=globalThis.XMLHttpRequest?.prototype;if(!t)return;let n=Symbol.for("goodlogs.xhr.patched");t.__gl_orig_open&&(t.open=t.__gl_orig_open),t.__gl_orig_set_header&&(t.setRequestHeader=t.__gl_orig_set_header),t.__gl_orig_send&&(t.send=t.__gl_orig_send),delete t.__gl_orig_open,delete t.__gl_orig_set_header,delete t.__gl_orig_send,delete t[n],this.xhrPatched=false;}attachClickCapture(){typeof document>"u"||(this.clickHandler=e=>{let t=e,n=t.target?.closest?.("a, button, [data-gl-event], [role='button']");if(!n)return;let r=n.getAttribute?.("data-gl-event"),i=n.tagName?.toLowerCase()??"",o=(n.textContent??"").trim().slice(0,50),a=n.getAttribute?.("href")??void 0,l=(n.className??"").toString().slice(0,80),u=globalThis,d=u.innerWidth,c=u.innerHeight,f=u.scrollY,g=typeof document<"u"?document.documentElement?.scrollHeight:void 0;this.track(r||"$click",{$element_tag:i,$element_id:n.id||void 0,$element_text:o||void 0,$element_href:a,$element_classes:l||void 0,$element_selector:te(n),$click_x:t.clientX,$click_y:t.clientY,$page_x:t.pageX,$page_y:t.pageY,$viewport_w:d,$viewport_h:c,$scroll_y:f,$doc_h:g,$url:typeof location<"u"?location.href:void 0,$pathname:typeof location<"u"?location.pathname: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 e=this.logBuffer.splice(0),t=this.eventBuffer.splice(0),n={"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,"X-GoodLogs-SDK":`js/${v}`};e.length>0&&fetch(`${this.endpoint}/v1/logs`,{method:"POST",headers:n,body:JSON.stringify({batch:e.map(r=>({severity:r.severity,message:r.message,properties:r.properties,timestamp:r.timestamp}))}),keepalive:true}).catch(()=>{}),t.length>0&&fetch(`${this.endpoint}/v1/events`,{method:"POST",headers:n,body:JSON.stringify({batch:t.map(r=>({event:r.event,distinctId:r.distinctId,properties:r.properties,timestamp:r.timestamp}))}),keepalive:true}).catch(()=>{});}sendTelemetry(e,t,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:e,level:t,metadata:{...n,sdk_version:v}}),keepalive:true}).catch(()=>{});}};T.MAX_BREADCRUMBS=50;var L=T;var A=class{constructor(e){if(!e.apiKey)throw new Error("apiKey is required");if(!e.apiKey.startsWith("gl_sk_"))throw new Error("GoodLogsClient requires a secret API key (gl_sk_...)");this.apiKey=e.apiKey,this.endpoint=y(e.apiKey,e.endpoint),this.timeout=e.timeout??3e4,this.alerts=new P(this),this.slos=new N(this),this.ai=new B(this);}async _request(e,t,n){let r=`${this.endpoint}${t}`,i={Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json"},o=new AbortController,a=setTimeout(()=>o.abort(),this.timeout);try{let l=await fetch(r,{method:e,headers:i,body:n?JSON.stringify(n):void 0,signal:o.signal});if(!l.ok){let u=await l.json().catch(()=>({})),d=u?.error?.message??`API error ${l.status}`;throw new I(l.status,d,u?.error?.code)}return l.status===204?void 0:await l.json()}finally{clearTimeout(a);}}_get(e){return this._request("GET",e)}_post(e,t){return this._request("POST",e,t)}_put(e,t){return this._request("PUT",e,t)}_delete(e){return this._request("DELETE",e)}info(){return this._get("/v1/info")}schema(){return this._get("/v1/schema")}gql(e){return this._post("/v1/gql/query",{q:e})}gqlBatch(e){return this._post("/v1/gql",{queries:e})}gqlAutocomplete(e,t){let n=`/v1/gql/autocomplete?q=${encodeURIComponent(e)}`;return t!==void 0&&(n+=`&cursor=${t}`),this._get(n)}nl2gql(e,t){return this._post("/v1/gql/nl",{prompt:e,mode:t})}},P=class{constructor(e){this.client=e;}list(){return this.client._get("/v1/alerts")}create(e){return this.client._post("/v1/alerts",e)}update(e,t){return this.client._put(`/v1/alerts/${e}`,t)}delete(e){return this.client._delete(`/v1/alerts/${e}`)}mute(e,t){return this.client._post(`/v1/alerts/${e}/mute`,{minutes:t})}},N=class{constructor(e){this.client=e;}list(){return this.client._get("/v1/slos")}create(e){return this.client._post("/v1/slos",e)}update(e,t){return this.client._put(`/v1/slos/${e}`,t)}delete(e){return this.client._delete(`/v1/slos/${e}`)}},B=class{constructor(e){this.client=e;}chat(e,t){return this.client._post("/v1/ai/chat",{message:e,session_id:t})}},I=class extends Error{constructor(t,n,r){super(n);this.status=t;this.code=r;this.name="GoodLogsApiError";}};var G="0.1.0";function le(s,e){let t=y(e?.apiKey??"",e?.endpoint).replace(/\/+$/,""),n={"Content-Type":"application/json","X-GoodLogs-SDK":G};e?.token&&(n.Authorization=`Bearer ${e.token}`),fetch(`${t}/v1/telemetry`,{method:"POST",headers:n,body:JSON.stringify({source:s.source,event:s.event,level:s.level??"info",metadata:{...s.metadata,sdk_version:G}}),keepalive:true}).catch(()=>{});}function x(s){if(!s)return null;let e=s.trim().split("-");if(e.length!==4)return null;let[t,n,r,i]=e;return t.length!==2||n.length!==32||r.length!==16||i.length!==2||!/^[0-9a-f]+$/.test(n)||!/^[0-9a-f]+$/.test(r)?null:{trace_id:n,parent_span_id:r}}function O(s,e){if(!s)return;let t=s[e]??s[e.toLowerCase()];return Array.isArray(t)?t[0]:t}function ue(s){return function(t,n,r){let i=(t.method??"GET").toUpperCase(),o=t.originalUrl??t.url??"",a=x(O(t.headers,"traceparent")),l=s.startTransaction({op:"http.server",name:`${i} ${o}`,trace_id:a?.trace_id,attributes:{"http.method":i,"http.url":o}}),u=false,d=()=>{if(u)return;u=true;let c=t.route?.path;c&&l.setAttribute("http.route",c);let f=n.statusCode??200;l.setAttribute("http.status_code",f),l.setStatus(f>=500?"error":"ok"),l.finish();};n.on("finish",d),n.on("close",d),t.goodlogs={span:l},r();}}function de(s){return function(t,n,r){t.addHook("onRequest",(i,o,a)=>{let l=(i.method??"GET").toUpperCase(),u=i.url??"",d=x(O(i.headers,"traceparent")),c=s.startTransaction({op:"http.server",name:`${l} ${u}`,trace_id:d?.trace_id,attributes:{"http.method":l,"http.url":u}});i.__goodlogsSpan=c,a();}),t.addHook("onResponse",(i,o,a)=>{let l=i.__goodlogsSpan;if(l){let u=i.routerPath??i.routeOptions?.url;u&&l.setAttribute("http.route",u);let d=o.statusCode??o.raw?.statusCode??200;l.setAttribute("http.status_code",d),l.setStatus(d>=500?"error":"ok"),l.finish();}a();}),r();}}function ce(s){return {intercept(e,t){let n=e.switchToHttp(),r=n.getRequest(),i=n.getResponse(),o=(r.method??"GET").toUpperCase(),a=r.originalUrl??r.url??"",l=x(O(r.headers,"traceparent")),u=s.startTransaction({op:"http.server",name:`${o} ${a}`,trace_id:l?.trace_id,attributes:{"http.method":o,"http.url":a}}),d=false,c=(g,h)=>{if(d)return;d=true;let p=r.route?.path;p&&u.setAttribute("http.route",p);let m=g??i.statusCode??200;u.setAttribute("http.status_code",m),u.setStatus(h||m>=500?"error":"ok"),u.finish();};i.on("finish",()=>c()),i.on("close",()=>c());let f=t.handle();if(f&&typeof f.subscribe=="function"){let g=f.subscribe({next:()=>{},error:h=>{u.setAttribute("error.message",h instanceof Error?h.message:String(h)),c(500,true);},complete:()=>c()});return {unsubscribe:()=>g.unsubscribe?.()}}return f}}}function pe(s){let e=globalThis.process;if(!e||typeof e.on!="function")return;let t=e,n=Symbol.for("goodlogs.node-process.patched");t[n]||(e.on("uncaughtException",r=>{try{s.captureException(r instanceof Error?r:new Error(String(r)),{tags:{source:"uncaughtException"},level:"fatal"}),s.flush();}catch{}}),e.on("unhandledRejection",r=>{try{let i=r instanceof Error?r:new Error(typeof r=="string"?r:(()=>{try{return JSON.stringify(r)}catch{return String(r)}})());s.captureException(i,{tags:{source:"unhandledRejection"}});}catch{}}),t[n]=true);}var M=globalThis.URL;function E(s){return !!M&&s instanceof M}var U=Symbol.for("goodlogs.node-http.patched");function fe(...s){let e=s[0],t=s[1],n="GET",r="";if(typeof e=="string")r=e,t&&typeof t=="object"&&!E(t)&&(n=String(t.method??n).toUpperCase());else if(E(e))r=e.toString(),t&&typeof t=="object"&&!E(t)&&(n=String(t.method??n).toUpperCase());else if(e&&typeof e=="object"){let o=e;n=String(o.method??n).toUpperCase();let a=(o.protocol??"http:").replace(":",""),l=o.hostname??o.host??"localhost",u=o.port?`:${o.port}`:"";r=`${a}://${l}${u}${o.path??"/"}`;}return {method:n,url:r,isOurs:o=>!!o&&r.startsWith(o)}}function he(s,e,t){let n=s[0]&&typeof s[0]=="object"&&!E(s[0])?s[0]:s[1]&&typeof s[1]=="object"&&!E(s[1])?s[1]:void 0;n&&(n.headers||(n.headers={}),!(e in n.headers)&&!(e.toLowerCase()in n.headers)&&(n.headers[e]=t));}function ge(s,e){let t=e?.endpoint??s.endpoint??"",n=r=>{let i=r;if(i[U])return;i[U]=true;let o=r.request.bind(r);r.request=function(...l){let{method:u,url:d,isOurs:c}=fe(...l);if(!d||c(t))return o(...l);let f=s.startTransaction({op:"http.client",name:`${u} ${d}`,attributes:{"http.method":u,"http.url":d}});he(l,"traceparent",`00-${f.trace_id}-${f.span_id}-01`);let g=false,h=(m,S)=>{g||(g=true,typeof m=="number"&&f.setAttribute("http.status_code",m),S?(f.setAttribute("error.message",S.message),f.setStatus("error")):f.setStatus(typeof m=="number"&&m>=500?"error":"ok"),f.finish());},p=o(...l);return p.on("response",m=>h(m.statusCode)),p.on("error",m=>h(void 0,m)),p.on("close",()=>h()),p};};if(typeof R=="function"){try{let r=R("http");n(r);}catch{}try{let r=R("https");n(r);}catch{}}}
|
|
7
|
+
exports.FlagClient=w;exports.GoodLogs=L;exports.GoodLogsApiError=I;exports.GoodLogsClient=A;exports.goodlogsExpress=ue;exports.goodlogsFastify=de;exports.goodlogsNestInterceptor=ce;exports.instrumentNodeHttp=ge;exports.instrumentNodeProcess=pe;exports.parseTraceparent=x;exports.resolveEndpoint=y;exports.resolveRegion=H;exports.sendTelemetry=le;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,54 @@
|
|
|
1
|
-
import { G as GoodLogs } from './client-
|
|
2
|
-
export { C as CaptureContext, E as ErrorBreadcrumb, a as ErrorEntry, b as ErrorFrame, c as EventEntry, d as GoodLogsOptions, L as LogEntry, S as Severity } from './client-
|
|
1
|
+
import { G as GoodLogs } from './client-D5LyyDBY.cjs';
|
|
2
|
+
export { C as CaptureContext, E as ErrorBreadcrumb, a as ErrorEntry, b as ErrorFrame, c as EventEntry, F as FeatureFlagOptions, d as GoodLogsOptions, L as LogEntry, S as Severity } from './client-D5LyyDBY.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Feature Flag client — polls flag definitions from the API, evaluates locally.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* const gl = new GoodLogs({ apiKey: "gl_pk_...", flags: true });
|
|
9
|
+
* gl.identify("user-123", { plan: "pro" });
|
|
10
|
+
* if (gl.isEnabled("new-checkout")) { ... }
|
|
11
|
+
* const variant = gl.getVariant("theme", "default");
|
|
12
|
+
*
|
|
13
|
+
* Evaluation is <1ms (in-memory). Polling happens every 30s in the background.
|
|
14
|
+
* Delta polling: only changed flags are fetched after the initial load.
|
|
15
|
+
*/
|
|
16
|
+
type FlagChangeCallback = (value: unknown) => void;
|
|
17
|
+
declare class FlagClient {
|
|
18
|
+
private endpoint;
|
|
19
|
+
private apiKey;
|
|
20
|
+
private pollInterval;
|
|
21
|
+
private flags;
|
|
22
|
+
private version;
|
|
23
|
+
private distinctId;
|
|
24
|
+
private properties;
|
|
25
|
+
private listeners;
|
|
26
|
+
private timer;
|
|
27
|
+
private ready;
|
|
28
|
+
private readyCallbacks;
|
|
29
|
+
constructor(endpoint: string, apiKey: string, pollInterval?: number);
|
|
30
|
+
/** Start polling. Call once after construction. */
|
|
31
|
+
start(): Promise<void>;
|
|
32
|
+
/** Stop polling. */
|
|
33
|
+
stop(): void;
|
|
34
|
+
/** Wait until flags are loaded. Resolves immediately if already ready. */
|
|
35
|
+
onReady(): Promise<void>;
|
|
36
|
+
/** Set user identity for flag evaluation. */
|
|
37
|
+
setUser(distinctId: string, properties?: Record<string, unknown>): void;
|
|
38
|
+
/** Check if a boolean flag is enabled.
|
|
39
|
+
* @param properties - Optional per-call properties (merged with setUser properties). Use on server where there's no persistent user session. */
|
|
40
|
+
isEnabled(key: string, defaultValue?: boolean, properties?: Record<string, unknown>): boolean;
|
|
41
|
+
/** Get a flag's resolved value (for multivariate / string / number flags).
|
|
42
|
+
* @param properties - Optional per-call properties (merged with setUser properties). */
|
|
43
|
+
getVariant<T = unknown>(key: string, defaultValue: T, properties?: Record<string, unknown>): T;
|
|
44
|
+
/** Get all flag values as a plain object. */
|
|
45
|
+
getAllFlags(): Record<string, unknown>;
|
|
46
|
+
/** Register a callback for when a flag value changes. Returns unsubscribe function. */
|
|
47
|
+
onFlagChange(key: string, callback: FlagChangeCallback): () => void;
|
|
48
|
+
private fetchAll;
|
|
49
|
+
private poll;
|
|
50
|
+
private applyUpdate;
|
|
51
|
+
}
|
|
3
52
|
|
|
4
53
|
interface LogRecord {
|
|
5
54
|
id: number;
|
|
@@ -473,4 +522,4 @@ declare function instrumentNodeHttp(gl: GoodLogs, opts?: {
|
|
|
473
522
|
endpoint?: string;
|
|
474
523
|
}): void;
|
|
475
524
|
|
|
476
|
-
export { type AiChatRequest, type AiChatResponse, type AiToolCall, type AlertRule, type CreateAlertRule, type CreateSlo, GoodLogs, GoodLogsApiError, GoodLogsClient, type GoodLogsClientOptions, type GqlAutocompleteResult, type GqlBatchResult, type GqlResult, type LogRecord, type MuteAlertRequest, type Nl2GqlResult, type NotifyChannel, type ProjectInfo, type SchemaField, type SchemaResponse, type SloDefinition, type TelemetryEvent, type TelemetryOptions, type UpdateAlertRule, type UpdateSlo, goodlogsExpress, goodlogsFastify, goodlogsNestInterceptor, instrumentNodeHttp, instrumentNodeProcess, parseTraceparent, resolveEndpoint, resolveRegion, sendTelemetry };
|
|
525
|
+
export { type AiChatRequest, type AiChatResponse, type AiToolCall, type AlertRule, type CreateAlertRule, type CreateSlo, FlagClient, GoodLogs, GoodLogsApiError, GoodLogsClient, type GoodLogsClientOptions, type GqlAutocompleteResult, type GqlBatchResult, type GqlResult, type LogRecord, type MuteAlertRequest, type Nl2GqlResult, type NotifyChannel, type ProjectInfo, type SchemaField, type SchemaResponse, type SloDefinition, type TelemetryEvent, type TelemetryOptions, type UpdateAlertRule, type UpdateSlo, goodlogsExpress, goodlogsFastify, goodlogsNestInterceptor, instrumentNodeHttp, instrumentNodeProcess, parseTraceparent, resolveEndpoint, resolveRegion, sendTelemetry };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,54 @@
|
|
|
1
|
-
import { G as GoodLogs } from './client-
|
|
2
|
-
export { C as CaptureContext, E as ErrorBreadcrumb, a as ErrorEntry, b as ErrorFrame, c as EventEntry, d as GoodLogsOptions, L as LogEntry, S as Severity } from './client-
|
|
1
|
+
import { G as GoodLogs } from './client-D5LyyDBY.js';
|
|
2
|
+
export { C as CaptureContext, E as ErrorBreadcrumb, a as ErrorEntry, b as ErrorFrame, c as EventEntry, F as FeatureFlagOptions, d as GoodLogsOptions, L as LogEntry, S as Severity } from './client-D5LyyDBY.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Feature Flag client — polls flag definitions from the API, evaluates locally.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* const gl = new GoodLogs({ apiKey: "gl_pk_...", flags: true });
|
|
9
|
+
* gl.identify("user-123", { plan: "pro" });
|
|
10
|
+
* if (gl.isEnabled("new-checkout")) { ... }
|
|
11
|
+
* const variant = gl.getVariant("theme", "default");
|
|
12
|
+
*
|
|
13
|
+
* Evaluation is <1ms (in-memory). Polling happens every 30s in the background.
|
|
14
|
+
* Delta polling: only changed flags are fetched after the initial load.
|
|
15
|
+
*/
|
|
16
|
+
type FlagChangeCallback = (value: unknown) => void;
|
|
17
|
+
declare class FlagClient {
|
|
18
|
+
private endpoint;
|
|
19
|
+
private apiKey;
|
|
20
|
+
private pollInterval;
|
|
21
|
+
private flags;
|
|
22
|
+
private version;
|
|
23
|
+
private distinctId;
|
|
24
|
+
private properties;
|
|
25
|
+
private listeners;
|
|
26
|
+
private timer;
|
|
27
|
+
private ready;
|
|
28
|
+
private readyCallbacks;
|
|
29
|
+
constructor(endpoint: string, apiKey: string, pollInterval?: number);
|
|
30
|
+
/** Start polling. Call once after construction. */
|
|
31
|
+
start(): Promise<void>;
|
|
32
|
+
/** Stop polling. */
|
|
33
|
+
stop(): void;
|
|
34
|
+
/** Wait until flags are loaded. Resolves immediately if already ready. */
|
|
35
|
+
onReady(): Promise<void>;
|
|
36
|
+
/** Set user identity for flag evaluation. */
|
|
37
|
+
setUser(distinctId: string, properties?: Record<string, unknown>): void;
|
|
38
|
+
/** Check if a boolean flag is enabled.
|
|
39
|
+
* @param properties - Optional per-call properties (merged with setUser properties). Use on server where there's no persistent user session. */
|
|
40
|
+
isEnabled(key: string, defaultValue?: boolean, properties?: Record<string, unknown>): boolean;
|
|
41
|
+
/** Get a flag's resolved value (for multivariate / string / number flags).
|
|
42
|
+
* @param properties - Optional per-call properties (merged with setUser properties). */
|
|
43
|
+
getVariant<T = unknown>(key: string, defaultValue: T, properties?: Record<string, unknown>): T;
|
|
44
|
+
/** Get all flag values as a plain object. */
|
|
45
|
+
getAllFlags(): Record<string, unknown>;
|
|
46
|
+
/** Register a callback for when a flag value changes. Returns unsubscribe function. */
|
|
47
|
+
onFlagChange(key: string, callback: FlagChangeCallback): () => void;
|
|
48
|
+
private fetchAll;
|
|
49
|
+
private poll;
|
|
50
|
+
private applyUpdate;
|
|
51
|
+
}
|
|
3
52
|
|
|
4
53
|
interface LogRecord {
|
|
5
54
|
id: number;
|
|
@@ -473,4 +522,4 @@ declare function instrumentNodeHttp(gl: GoodLogs, opts?: {
|
|
|
473
522
|
endpoint?: string;
|
|
474
523
|
}): void;
|
|
475
524
|
|
|
476
|
-
export { type AiChatRequest, type AiChatResponse, type AiToolCall, type AlertRule, type CreateAlertRule, type CreateSlo, GoodLogs, GoodLogsApiError, GoodLogsClient, type GoodLogsClientOptions, type GqlAutocompleteResult, type GqlBatchResult, type GqlResult, type LogRecord, type MuteAlertRequest, type Nl2GqlResult, type NotifyChannel, type ProjectInfo, type SchemaField, type SchemaResponse, type SloDefinition, type TelemetryEvent, type TelemetryOptions, type UpdateAlertRule, type UpdateSlo, goodlogsExpress, goodlogsFastify, goodlogsNestInterceptor, instrumentNodeHttp, instrumentNodeProcess, parseTraceparent, resolveEndpoint, resolveRegion, sendTelemetry };
|
|
525
|
+
export { type AiChatRequest, type AiChatResponse, type AiToolCall, type AlertRule, type CreateAlertRule, type CreateSlo, FlagClient, GoodLogs, GoodLogsApiError, GoodLogsClient, type GoodLogsClientOptions, type GqlAutocompleteResult, type GqlBatchResult, type GqlResult, type LogRecord, type MuteAlertRequest, type Nl2GqlResult, type NotifyChannel, type ProjectInfo, type SchemaField, type SchemaResponse, type SloDefinition, type TelemetryEvent, type TelemetryOptions, type UpdateAlertRule, type UpdateSlo, goodlogsExpress, goodlogsFastify, goodlogsNestInterceptor, instrumentNodeHttp, instrumentNodeProcess, parseTraceparent, resolveEndpoint, resolveRegion, sendTelemetry };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
var
|
|
2
|
-
`);if(!e)return;for(let t=3;t<Math.min(e.length,8);t++){let n=e[t]?.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
|
|
3
|
-
`)){let n=t.trim();if(!n||n.startsWith("Error")||n.startsWith("at Error"))continue;let r=/^at\s+(?:(.+?)\s+\()?(.+?):(\d+):(\d+)\)?$/.exec(n);if(r){let
|
|
1
|
+
var R=(s=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(s,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):s)(function(s){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+s+'" is not supported')});function H(s){let e=s.split("_");return e.length>=4&&e[0]==="gl"?e[2]:"eu"}function D(s,e){return s==="eu"&&(!e||e==="production")?"https://api.goodlogs.dev":s==="eu"?`https://api-${e}.goodlogs.dev`:!e||e==="production"?`https://api-${s}.goodlogs.dev`:`https://api-${s}-${e}.goodlogs.dev`}function y(s,e,t){if(e)return e;let n=H(s);return D(n,t)}var K=(()=>{let s=[];for(let e=0;e<256;e++){let t=e;for(let n=0;n<8;n++)t=t&1?3988292384^t>>>1:t>>>1;s[e]=t;}return s})();function j(s){let e=4294967295;for(let t=0;t<s.length;t++)e=K[(e^s.charCodeAt(t))&255]^e>>>8;return (e^4294967295)>>>0}function k(s,e,t){if(!s.enabled)return s.default_value;if(s.overrides&&e in s.overrides)return s.overrides[e];for(let n of s.rules)if(V(n.conditions,t)){if(n.rollout_percentage<100&&j(`${s.key}:${e}`)%100>=n.rollout_percentage)continue;return s.variants.length>0&&n.variant?W(s.variants,s.key,e):n.value}return s.default_value}function V(s,e){return s.length===0?true:s.every(t=>X(t,e))}function X(s,e){let t=e[s.property],n=s.operator;if(n==="is_set")return t!=null;if(n==="is_not_set")return t==null;if(n==="eq")return C(t,s.value);if(n==="neq")return !C(t,s.value);let r=q(t),i=q(s.value);return n==="gt"?r!==null&&i!==null&&r>i:n==="gte"?r!==null&&i!==null&&r>=i:n==="lt"?r!==null&&i!==null&&r<i:n==="lte"?r!==null&&i!==null&&r<=i:n==="in"&&Array.isArray(s.value)?s.value.some(o=>C(t,o)):n==="not_in"&&Array.isArray(s.value)?!s.value.some(o=>C(t,o)):n==="contains"?String(t??"").toLowerCase().includes(String(s.value??"").toLowerCase()):n==="not_contains"?!String(t??"").toLowerCase().includes(String(s.value??"").toLowerCase()):false}function C(s,e){if(s===e)return true;let t=String(s??"").toLowerCase(),n=String(e??"").toLowerCase();return t===n}function q(s){if(typeof s=="number")return s;if(typeof s=="string"){let e=parseFloat(s);return isNaN(e)?null:e}return null}function W(s,e,t){if(s.length===0)return null;let n=j(`${e}:variant:${t}`)%1e4,r=0;for(let i of s)if(r+=i.weight*100,n<r)return i.value;return s[s.length-1]?.value??null}var w=class{constructor(e,t,n=3e4){this.flags=new Map;this.version=0;this.distinctId="";this.properties={};this.listeners=new Map;this.timer=null;this.ready=false;this.readyCallbacks=[];this.endpoint=e,this.apiKey=t,this.pollInterval=n;}async start(){await this.fetchAll(),this.ready=true;for(let e of this.readyCallbacks)e();this.readyCallbacks=[],this.timer=setInterval(()=>this.poll(),this.pollInterval);}stop(){this.timer&&(clearInterval(this.timer),this.timer=null);}onReady(){return this.ready?Promise.resolve():new Promise(e=>this.readyCallbacks.push(e))}setUser(e,t){this.distinctId=e,t&&(this.properties={...t});}isEnabled(e,t=false,n){let r=this.flags.get(e);if(!r)return t;let i=n?{...this.properties,...n}:this.properties,o=k(r,this.distinctId,i);return o===true||o==="true"}getVariant(e,t,n){let r=this.flags.get(e);if(!r)return t;let i=n?{...this.properties,...n}:this.properties;return k(r,this.distinctId,i)??t}getAllFlags(){let e={};for(let[t,n]of this.flags)e[t]=k(n,this.distinctId,this.properties);return e}onFlagChange(e,t){let n=this.listeners.get(e);return n||(n=new Set,this.listeners.set(e,n)),n.add(t),()=>n.delete(t)}async fetchAll(){try{let e=await fetch(`${this.endpoint}/v1/flags`,{headers:{"x-api-key":this.apiKey}});if(!e.ok)return;let t=await e.json();this.applyUpdate(t.flags??[],t.version??0);}catch{}}async poll(){try{let e=await fetch(`${this.endpoint}/v1/flags?since_version=${this.version}`,{headers:{"x-api-key":this.apiKey}});if(e.status===304||!e.ok)return;let t=await e.json();this.applyUpdate(t.flags??[],t.version??0);}catch{}}applyUpdate(e,t){let n=new Map;for(let r of e){let i=this.flags.get(r.key);i&&n.set(r.key,k(i,this.distinctId,this.properties));}for(let r of e)this.flags.set(r.key,r);t>this.version&&(this.version=t);for(let r of e){let i=n.get(r.key),o=k(r,this.distinctId,this.properties);i!==void 0&&i!==o&&this.listeners.get(r.key)?.forEach(a=>{try{a(o);}catch{}});}}};var J=5e3,z=50,v="0.5.6",$="gl_anon_id",_="gl_session_id";function b(){return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,s=>{let e=Math.random()*16|0;return (s==="x"?e:e&3|8).toString(16)})}function Y(){let s={$goodlogs_sdk:"js",$goodlogs_sdk_version:v};return typeof navigator>"u"||(typeof screen<"u"&&(s.$screen=`${screen.width}x${screen.height}`),typeof navigator<"u"&&(s.$language=navigator.language??""),typeof location<"u"&&(s.$url=location.href,s.$path=location.pathname,s.$page=location.pathname.split("/").filter(Boolean).pop()||"/"),typeof document<"u"&&(document.referrer&&(s.$referrer=document.referrer),document.title&&(s.$title=document.title))),s}function Q(s,e){let t={$session_id:s,$distinct_id:e,$goodlogs_sdk:"js",$goodlogs_sdk_version:v};return typeof navigator>"u"||typeof location<"u"&&(t.$url=location.href,t.$path=location.pathname),t}function Z(s,e,t,n,r){let i=Q(s,e);return t&&(i.$release=t),i.$environment=n,r.email&&(i.$user_email=r.email),r.name&&(i.$user_name=r.name),i}function ee(){if(!(typeof document<"u"))try{let e=new Error().stack?.split(`
|
|
2
|
+
`);if(!e)return;for(let t=3;t<Math.min(e.length,8);t++){let n=e[t]?.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 i=r[1]||"<anonymous>",o=r[2]?.replace(/^.*[/\\]/,"")??"",a=r[3];return `${i}@${o}:${a}`}}}catch{}}function te(s){let e=[],t=s;for(;t&&t.tagName;){let n=t.tagName.toLowerCase();if(n==="html"||n==="body"){e.unshift(n);break}if(t.id){e.unshift(`#${t.id}`);break}let r=1,i=t;for(;i?.previousElementSibling;)i.previousElementSibling.tagName?.toLowerCase()===n&&r++,i=i.previousElementSibling;e.unshift(r>1?`${n}:nth-of-type(${r})`:n),t=t.parentElement;}return e.join(" > ").slice(0,200)}function ne(){if(typeof localStorage<"u"){let s=localStorage.getItem($);if(s)return s;let e=b();return localStorage.setItem($,e),e}return b()}function re(){if(typeof sessionStorage<"u"){let s=sessionStorage.getItem(_);if(s)return s;let e=b();return sessionStorage.setItem(_,e),e}return b()}function ie(){let s="";for(let e=0;e<32;e++)s+=(Math.random()*16|0).toString(16);return s}function se(){let s="";for(let e=0;e<16;e++)s+=(Math.random()*16|0).toString(16);return s}function oe(s,e){switch(s){case "lcp":return e<=2500?"good":e<=4e3?"needs-improvement":"poor";case "inp":return e<=200?"good":e<=500?"needs-improvement":"poor";case "cls":return e<=.1?"good":e<=.25?"needs-improvement":"poor";case "fcp":return e<=1800?"good":e<=3e3?"needs-improvement":"poor";case "ttfb":return e<=800?"good":e<=1800?"needs-improvement":"poor";case "dns":return e<=20?"good":e<=100?"needs-improvement":"poor";case "tcp":return e<=50?"good":e<=200?"needs-improvement":"poor";case "download":return e<=100?"good":e<=500?"needs-improvement":"poor";case "dom_processing":return e<=500?"good":e<=1500?"needs-improvement":"poor";case "page_load":return e<=1e3?"good":e<=3e3?"needs-improvement":"poor";default:return}}function ae(s){if(!s)return [];let e=[];for(let t of s.split(`
|
|
3
|
+
`)){let n=t.trim();if(!n||n.startsWith("Error")||n.startsWith("at Error"))continue;let r=/^at\s+(?:(.+?)\s+\()?(.+?):(\d+):(\d+)\)?$/.exec(n);if(r){let i=r[1]?.trim(),o=r[2];e.push({function:i&&i!=="<anonymous>"?i:void 0,filename:o,lineno:Number(r[3]),colno:Number(r[4]),abs_path:o,in_app:!o.includes("node_modules/")&&!o.includes("/dist/")&&!o.startsWith("internal/")});continue}if(r=/^([^@]*)@(.+?):(\d+):(\d+)$/.exec(n),r){let i=r[1]?.trim(),o=r[2];e.push({function:i||void 0,filename:o,lineno:Number(r[3]),colno:Number(r[4]),abs_path:o,in_app:!o.includes("node_modules/")&&!o.includes("/dist/")});}}return e}var T=class T{constructor(e){this.userProperties={};this.originalFetch=null;this.xhrPatched=false;this._debug=false;this.beforeSend=null;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.flagClient=null;if(this.apiKey=e.apiKey,this.endpoint=y(e.apiKey,e.endpoint,e.environment).replace(/\/+$/,""),this.flushInterval=e.flushInterval??J,this.batchSize=e.batchSize??z,this.defaultContext=e.defaultContext??{},this.onError=e.onError??(()=>{}),this.disabled=e.disabled??false,this.telemetry=e.telemetry??true,this.useEnvelope=e.useEnvelope??false,this.autoFetch=e.autoFetch??(this.useEnvelope&&e.autocapture!==false),this.release=e.release??null,this.environment=e.environment??"production",this._debug=e.debug??false,this.beforeSend=e.beforeSend??null,this.anonymousId=ne(),this.sessionId=re(),this._debug&&this._log("init",{endpoint:this.endpoint,sessionId:this.sessionId,distinctId:this.anonymousId,release:this.release,env:this.environment,envelope:this.useEnvelope,autoFetch:this.autoFetch}),this.disabled&&typeof console<"u"&&console.warn("[GoodLogs] SDK is disabled. No events or logs will be sent."),!this.disabled&&typeof setTimeout<"u"&&setTimeout(()=>{!this.release&&typeof console<"u"&&console.warn("[GoodLogs] No release version set. Set `release` in options or call gl.setRelease('1.2.3') for release health tracking.");},5e3),!this.disabled&&(this.startTimer(),this.attachPageLifecycle(),e.autocapture!==false&&(this.attachClickCapture(),this.captureWebVitals(),this.attachPageviewCapture(),this.attachGlobalErrorHandlers(),this.attachAutoBreadcrumbs()),this.autoFetch&&(this.attachFetchInstrumentation(),this.attachXhrInstrumentation()),this.sendTelemetry("init","info"),e.flags)){let t=typeof e.flags=="object"?e.flags:{};this.flagClient=new w(this.endpoint,this.apiKey,t.pollInterval??3e4),t.properties&&this.flagClient.setUser(this.anonymousId,t.properties),this.flagClient.start().catch(()=>{});}}log(e,t,n){if(this.disabled)return;let r=65536,i=t;t.length>r&&(i=t.slice(0,r-100)+`
|
|
4
4
|
|
|
5
|
-
[truncated \u2014 original ${t.length} chars, limit ${r}]`,this.onError(new Error(`Log message truncated from ${t.length} to ${r} chars`)));let
|
|
6
|
-
`);await this.postEnvelopeWithRetry(f,u);}}async postEnvelopeWithRetry(e,t,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:e});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(e,t,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 t)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 t)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(e,t,n,r=0){try{let s=await fetch(`${this.endpoint}${e}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,"X-GoodLogs-SDK":`js/${v}`},body:JSON.stringify({batch:t})});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(u=>setTimeout(u,d+a)),this.postWithRetry(e,t,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(t);return}let i=await s.json().catch(()=>null);if(i&&i.rejected&&i.rejected>0){let d=t.slice(i.accepted??0);d.length>0&&n(d);}}catch(s){let i=s instanceof Error?s:new Error(String(s));r===0&&n(t),this.onError(i);}}startTimer(){this.timer=setInterval(()=>{this.flush();},this.flushInterval);let e=this.timer;typeof e?.unref=="function"&&e.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 e=(t,n)=>{if(this.useEnvelope)this.captureVital(t.toLowerCase(),n);else {let r=t==="CLS"?"$value":"$value_ms";this.track("$web_vital",{properties:{$metric:t,[r]:t==="CLS"?n:Math.round(n)}});}};try{new PerformanceObserver(t=>{let n=t.getEntries()[0];n&&e("FCP",n.startTime);}).observe({type:"paint",buffered:!0});}catch{}try{new PerformanceObserver(t=>{let n=t.getEntries(),r=n[n.length-1];r&&e("LCP",r.startTime);}).observe({type:"largest-contentful-paint",buffered:!0});}catch{}try{let t=0;if(new PerformanceObserver(n=>{for(let r of n.getEntries())r.hadRecentInput||(t+=r.value);}).observe({type:"layout-shift",buffered:!0}),typeof document<"u"){let n=()=>{t>0&&e("CLS",Math.round(t*1e3)/1e3);};document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&n();});}}catch{}try{new PerformanceObserver(t=>{for(let n of t.getEntries()){let r=n;r.responseStart&&r.responseStart>0&&e("TTFB",r.responseStart);let s=c=>c&&Number.isFinite(c)&&c>0?c:0,i=s(r.domainLookupEnd)-s(r.domainLookupStart);i>0&&this.captureVital("dns",i);let d=s(r.connectEnd)-s(r.connectStart);d>0&&this.captureVital("tcp",d);let a=s(r.responseEnd)-s(r.responseStart);a>0&&this.captureVital("download",a);let u=s(r.domComplete)-s(r.responseEnd);u>0&&this.captureVital("dom_processing",u);let l=s(r.loadEventEnd)-s(r.fetchStart);l>0&&this.captureVital("page_load",l);}}).observe({type:"navigation",buffered:!0});}catch{try{if(typeof performance<"u"){let t=performance.getEntriesByType?.("navigation")?.[0];t?.responseStart&&e("TTFB",t.responseStart);let n=u=>u&&Number.isFinite(u)&&u>0?u:0,r=n(t?.domainLookupEnd)-n(t?.domainLookupStart);r>0&&this.captureVital("dns",r);let s=n(t?.connectEnd)-n(t?.connectStart);s>0&&this.captureVital("tcp",s);let i=n(t?.responseEnd)-n(t?.responseStart);i>0&&this.captureVital("download",i);let d=n(t?.domComplete)-n(t?.responseEnd);d>0&&this.captureVital("dom_processing",d);let a=n(t?.loadEventEnd)-n(t?.fetchStart);a>0&&this.captureVital("page_load",a);}}catch{}}try{new PerformanceObserver(t=>{for(let n of t.getEntries()){let r=n.duration;r>0&&e("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 e=(t="push")=>{typeof location<"u"&&location.pathname!==this.lastPath&&(this.lastPath=location.pathname,this.track("$pageview"),this.startNavTransaction(this.lastPath,t));};if(typeof history<"u"){let t=history.pushState,n=history.replaceState;history.pushState=function(...r){t.apply(this,r),e("push");},history.replaceState=function(...r){n.apply(this,r),e("replace");};}typeof addEventListener<"u"&&addEventListener("popstate",()=>e("popstate"));}startNavTransaction(e,t){try{this.navTransaction&&(this.navTransaction.finish(),this.navTransaction=null),this.navTransaction=this.startTransaction({op:"navigation",name:e,attributes:{"navigation.type":t,"http.url":typeof location<"u"?location.href:e}});let n=this.navTransaction;setTimeout(()=>{this.navTransaction===n&&(n.finish(),this.navTransaction=null);},3e4);}catch{}}attachGlobalErrorHandlers(){let e=globalThis;typeof e.addEventListener=="function"&&(this.errorHandler||this.rejectionHandler||(this.errorHandler=t=>{let n=t,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=t=>{let r=t.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{}},e.addEventListener("error",this.errorHandler),e.addEventListener("unhandledrejection",this.rejectionHandler)));}detachGlobalErrorHandlers(){let e=globalThis;typeof e.removeEventListener=="function"&&(this.errorHandler&&(e.removeEventListener("error",this.errorHandler),this.errorHandler=null),this.rejectionHandler&&(e.removeEventListener("unhandledrejection",this.rejectionHandler),this.rejectionHandler=null));}attachAutoBreadcrumbs(){if(typeof console<"u"){let e=this,t=["error","warn","info","log"];for(let n of t){let r=console[n];r&&(console[n]=function(...s){try{e.addBreadcrumb({category:"console",message:s.map(i=>typeof i=="string"?i:JSON.stringify(i)).join(" ").slice(0,500),level:n==="error"?"error":n==="warn"?"warning":"info"});}catch{}return r.apply(console,s)});}}if(typeof globalThis<"u"&&typeof globalThis.history<"u"){let e=this,t=globalThis,n=t.history.pushState;t.history.pushState=function(...r){try{e.addBreadcrumb({category:"navigation",message:`\u2192 ${String(r[2]??"")}`,level:"info"});}catch{}return n.apply(t.history,r)},t.addEventListener("popstate",()=>{try{e.addBreadcrumb({category:"navigation",message:`\u2190 ${t.location.pathname}`,level:"info"});}catch{}});}}attachFetchInstrumentation(){if(typeof fetch>"u")return;let e=globalThis;if(this.originalFetch)return;this.originalFetch=e.fetch;let t=e.fetch.bind(globalThis),n=this;e.fetch=function(s,i){let d="",a="GET";if(typeof s=="string")d=s;else if(s&&typeof s=="object"){let c=s;d=c.url??"",a=c.method??a;}let u=i??{};if(u.method?a=String(u.method).toUpperCase():typeof s=="object"&&(a=s.method?.toUpperCase()??a),d.startsWith(n.endpoint))return t(s,u);let l=n.startSpan({op:"http.client",name:`${a} ${d}`,attributes:{"http.method":a,"http.url":d},parent:n.navTransaction??void 0});try{let c=`00-${l.trace_id}-${l.span_id}-01`,f={...u},g=f.headers??{};return f.headers={...g,traceparent:c},t(s,f).then(h=>{let p=h;return typeof p.status=="number"&&l.setAttribute("http.status_code",p.status),l.setStatus(p.ok===!1?"error":"ok"),l.finish(),h}).catch(h=>{throw l.setStatus("error"),l.setAttribute("error.message",h instanceof Error?h.message:String(h)),l.finish(),h})}catch(c){throw l.setStatus("error"),l.finish(),c}};}detachFetchInstrumentation(){this.originalFetch&&(globalThis.fetch=this.originalFetch,this.originalFetch=null);}attachXhrInstrumentation(){let t=globalThis.XMLHttpRequest;if(!t||!t.prototype)return;let n=Symbol.for("goodlogs.xhr.patched"),r=t.prototype;if(r[n]){this.xhrPatched=true;return}let s=r.open,i=r.setRequestHeader,d=r.send,a=this;r.open=function(l,c,...f){return this.__gl_method=typeof l=="string"?l.toUpperCase():"GET",this.__gl_url=typeof c=="string"?c:String(c??""),this.__gl_headers_set=false,s.apply(this,[l,c,...f])},r.setRequestHeader=function(l,c){return this.__gl_headers_set=true,i.apply(this,[l,c])},r.send=function(l){let c=this.__gl_url||"",f=this.__gl_method||"GET";if(c.startsWith(a.endpoint))return d.apply(this,[l]);let g=a.startSpan({op:"http.client",name:`${f} ${c}`,attributes:{"http.method":f,"http.url":c},parent:a.navTransaction??void 0});try{let m=`00-${g.trace_id}-${g.span_id}-01`;i.apply(this,["traceparent",m]);}catch{}let h=(m,_,N)=>{m&&g.setAttribute("http.status_code",m),N&&g.setAttribute("error.message",N),g.setStatus(_?"ok":"error"),g.finish();},p=this.addEventListener;return typeof p=="function"?(p.call(this,"load",()=>{let m=Number(this.status||0);h(m,m>0&&m<500);}),p.call(this,"error",()=>h(0,false,"network error")),p.call(this,"abort",()=>h(0,false,"aborted")),p.call(this,"timeout",()=>h(0,false,"timeout"))):h(0,true),d.apply(this,[l])},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 t=globalThis.XMLHttpRequest?.prototype;if(!t)return;let n=Symbol.for("goodlogs.xhr.patched");t.__gl_orig_open&&(t.open=t.__gl_orig_open),t.__gl_orig_set_header&&(t.setRequestHeader=t.__gl_orig_set_header),t.__gl_orig_send&&(t.send=t.__gl_orig_send),delete t.__gl_orig_open,delete t.__gl_orig_set_header,delete t.__gl_orig_send,delete t[n],this.xhrPatched=false;}attachClickCapture(){typeof document>"u"||(this.clickHandler=e=>{let t=e,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),u=globalThis,l=u.innerWidth,c=u.innerHeight,f=u.scrollY,g=typeof document<"u"?document.documentElement?.scrollHeight:void 0;this.track(r||"$click",{$element_tag:s,$element_id:n.id||void 0,$element_text:i||void 0,$element_href:d,$element_classes:a||void 0,$element_selector:X(n),$click_x:t.clientX,$click_y:t.clientY,$page_x:t.pageX,$page_y:t.pageY,$viewport_w:l,$viewport_h:c,$scroll_y:f,$doc_h:g,$url:typeof location<"u"?location.href:void 0,$pathname:typeof location<"u"?location.pathname: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 e=this.logBuffer.splice(0),t=this.eventBuffer.splice(0),n={"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,"X-GoodLogs-SDK":`js/${v}`};e.length>0&&fetch(`${this.endpoint}/v1/logs`,{method:"POST",headers:n,body:JSON.stringify({batch:e.map(r=>({severity:r.severity,message:r.message,properties:r.properties,timestamp:r.timestamp}))}),keepalive:true}).catch(()=>{}),t.length>0&&fetch(`${this.endpoint}/v1/events`,{method:"POST",headers:n,body:JSON.stringify({batch:t.map(r=>({event:r.event,distinctId:r.distinctId,properties:r.properties,timestamp:r.timestamp}))}),keepalive:true}).catch(()=>{});}sendTelemetry(e,t,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:e,level:t,metadata:{...n,sdk_version:v}}),keepalive:true}).catch(()=>{});}};R.MAX_BREADCRUMBS=50;var I=R;var C=class{constructor(e){if(!e.apiKey)throw new Error("apiKey is required");if(!e.apiKey.startsWith("gl_sk_"))throw new Error("GoodLogsClient requires a secret API key (gl_sk_...)");this.apiKey=e.apiKey,this.endpoint=y(e.apiKey,e.endpoint),this.timeout=e.timeout??3e4,this.alerts=new x(this),this.slos=new L(this),this.ai=new P(this);}async _request(e,t,n){let r=`${this.endpoint}${t}`,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:e,headers:s,body:n?JSON.stringify(n):void 0,signal:i.signal});if(!a.ok){let u=await a.json().catch(()=>({})),l=u?.error?.message??`API error ${a.status}`;throw new T(a.status,l,u?.error?.code)}return a.status===204?void 0:await a.json()}finally{clearTimeout(d);}}_get(e){return this._request("GET",e)}_post(e,t){return this._request("POST",e,t)}_put(e,t){return this._request("PUT",e,t)}_delete(e){return this._request("DELETE",e)}info(){return this._get("/v1/info")}schema(){return this._get("/v1/schema")}gql(e){return this._post("/v1/gql/query",{q:e})}gqlBatch(e){return this._post("/v1/gql",{queries:e})}gqlAutocomplete(e,t){let n=`/v1/gql/autocomplete?q=${encodeURIComponent(e)}`;return t!==void 0&&(n+=`&cursor=${t}`),this._get(n)}nl2gql(e,t){return this._post("/v1/gql/nl",{prompt:e,mode:t})}},x=class{constructor(e){this.client=e;}list(){return this.client._get("/v1/alerts")}create(e){return this.client._post("/v1/alerts",e)}update(e,t){return this.client._put(`/v1/alerts/${e}`,t)}delete(e){return this.client._delete(`/v1/alerts/${e}`)}mute(e,t){return this.client._post(`/v1/alerts/${e}/mute`,{minutes:t})}},L=class{constructor(e){this.client=e;}list(){return this.client._get("/v1/slos")}create(e){return this.client._post("/v1/slos",e)}update(e,t){return this.client._put(`/v1/slos/${e}`,t)}delete(e){return this.client._delete(`/v1/slos/${e}`)}},P=class{constructor(e){this.client=e;}chat(e,t){return this.client._post("/v1/ai/chat",{message:e,session_id:t})}},T=class extends Error{constructor(t,n,r){super(n);this.status=t;this.code=r;this.name="GoodLogsApiError";}};var O="0.1.0";function Z(o,e){let t=y(e?.apiKey??"",e?.endpoint).replace(/\/+$/,""),n={"Content-Type":"application/json","X-GoodLogs-SDK":O};e?.token&&(n.Authorization=`Bearer ${e.token}`),fetch(`${t}/v1/telemetry`,{method:"POST",headers:n,body:JSON.stringify({source:o.source,event:o.event,level:o.level??"info",metadata:{...o.metadata,sdk_version:O}}),keepalive:true}).catch(()=>{});}function $(o){if(!o)return null;let e=o.trim().split("-");if(e.length!==4)return null;let[t,n,r,s]=e;return t.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 A(o,e){if(!o)return;let t=o[e]??o[e.toLowerCase()];return Array.isArray(t)?t[0]:t}function ee(o){return function(t,n,r){let s=(t.method??"GET").toUpperCase(),i=t.originalUrl??t.url??"",d=$(A(t.headers,"traceparent")),a=o.startTransaction({op:"http.server",name:`${s} ${i}`,trace_id:d?.trace_id,attributes:{"http.method":s,"http.url":i}}),u=false,l=()=>{if(u)return;u=true;let c=t.route?.path;c&&a.setAttribute("http.route",c);let f=n.statusCode??200;a.setAttribute("http.status_code",f),a.setStatus(f>=500?"error":"ok"),a.finish();};n.on("finish",l),n.on("close",l),t.goodlogs={span:a},r();}}function te(o){return function(t,n,r){t.addHook("onRequest",(s,i,d)=>{let a=(s.method??"GET").toUpperCase(),u=s.url??"",l=$(A(s.headers,"traceparent")),c=o.startTransaction({op:"http.server",name:`${a} ${u}`,trace_id:l?.trace_id,attributes:{"http.method":a,"http.url":u}});s.__goodlogsSpan=c,d();}),t.addHook("onResponse",(s,i,d)=>{let a=s.__goodlogsSpan;if(a){let u=s.routerPath??s.routeOptions?.url;u&&a.setAttribute("http.route",u);let l=i.statusCode??i.raw?.statusCode??200;a.setAttribute("http.status_code",l),a.setStatus(l>=500?"error":"ok"),a.finish();}d();}),r();}}function ne(o){return {intercept(e,t){let n=e.switchToHttp(),r=n.getRequest(),s=n.getResponse(),i=(r.method??"GET").toUpperCase(),d=r.originalUrl??r.url??"",a=$(A(r.headers,"traceparent")),u=o.startTransaction({op:"http.server",name:`${i} ${d}`,trace_id:a?.trace_id,attributes:{"http.method":i,"http.url":d}}),l=false,c=(g,h)=>{if(l)return;l=true;let p=r.route?.path;p&&u.setAttribute("http.route",p);let m=g??s.statusCode??200;u.setAttribute("http.status_code",m),u.setStatus(h||m>=500?"error":"ok"),u.finish();};s.on("finish",()=>c()),s.on("close",()=>c());let f=t.handle();if(f&&typeof f.subscribe=="function"){let g=f.subscribe({next:()=>{},error:h=>{u.setAttribute("error.message",h instanceof Error?h.message:String(h)),c(500,true);},complete:()=>c()});return {unsubscribe:()=>g.unsubscribe?.()}}return f}}}function re(o){let e=globalThis.process;if(!e||typeof e.on!="function")return;let t=e,n=Symbol.for("goodlogs.node-process.patched");t[n]||(e.on("uncaughtException",r=>{try{o.captureException(r instanceof Error?r:new Error(String(r)),{tags:{source:"uncaughtException"},level:"fatal"}),o.flush();}catch{}}),e.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{}}),t[n]=true);}var H=globalThis.URL;function E(o){return !!H&&o instanceof H}var q=Symbol.for("goodlogs.node-http.patched");function se(...o){let e=o[0],t=o[1],n="GET",r="";if(typeof e=="string")r=e,t&&typeof t=="object"&&!E(t)&&(n=String(t.method??n).toUpperCase());else if(E(e))r=e.toString(),t&&typeof t=="object"&&!E(t)&&(n=String(t.method??n).toUpperCase());else if(e&&typeof e=="object"){let i=e;n=String(i.method??n).toUpperCase();let d=(i.protocol??"http:").replace(":",""),a=i.hostname??i.host??"localhost",u=i.port?`:${i.port}`:"";r=`${d}://${a}${u}${i.path??"/"}`;}return {method:n,url:r,isOurs:i=>!!i&&r.startsWith(i)}}function ie(o,e,t){let n=o[0]&&typeof o[0]=="object"&&!E(o[0])?o[0]:o[1]&&typeof o[1]=="object"&&!E(o[1])?o[1]:void 0;n&&(n.headers||(n.headers={}),!(e in n.headers)&&!(e.toLowerCase()in n.headers)&&(n.headers[e]=t));}function oe(o,e){let t=e?.endpoint??o.endpoint??"",n=r=>{let s=r;if(s[q])return;s[q]=true;let i=r.request.bind(r);r.request=function(...a){let{method:u,url:l,isOurs:c}=se(...a);if(!l||c(t))return i(...a);let f=o.startTransaction({op:"http.client",name:`${u} ${l}`,attributes:{"http.method":u,"http.url":l}});ie(a,"traceparent",`00-${f.trace_id}-${f.span_id}-01`);let g=false,h=(m,_)=>{g||(g=true,typeof m=="number"&&f.setAttribute("http.status_code",m),_?(f.setAttribute("error.message",_.message),f.setStatus("error")):f.setStatus(typeof m=="number"&&m>=500?"error":"ok"),f.finish());},p=i(...a);return p.on("response",m=>h(m.statusCode)),p.on("error",m=>h(void 0,m)),p.on("close",()=>h()),p};};if(typeof w=="function"){try{let r=w("http");n(r);}catch{}try{let r=w("https");n(r);}catch{}}}
|
|
7
|
-
export{
|
|
5
|
+
[truncated \u2014 original ${t.length} chars, limit ${r}]`,this.onError(new Error(`Log message truncated from ${t.length} to ${r} chars`)));let o=ee(),a={severity:e,message:i,properties:{...this.defaultContext,...Z(this.sessionId,this.anonymousId,this.release,this.environment,this.userProperties),...o?{code_location:o}:{},...n},timestamp:new Date().toISOString()};this.logBuffer.push(a),this.logBuffer.length>=this.batchSize&&this.flush();}debug(e,t){this.log("debug",e,t);}info(e,t){this.log("info",e,t);}warn(e,t){this.log("warn",e,t);}error(e,t){this.log("error",e,t);}fatal(e,t){this.log("fatal",e,t);}identify(e){this.anonymousId=e,typeof localStorage<"u"&&localStorage.setItem($,e);}getDistinctId(){return this.anonymousId}reset(){this.anonymousId=b(),this.sessionId=b(),typeof localStorage<"u"&&localStorage.setItem($,this.anonymousId),typeof sessionStorage<"u"&&sessionStorage.setItem(_,this.sessionId);}getSessionId(){return this.sessionId}newSession(){this.sessionId=b(),typeof sessionStorage<"u"&&sessionStorage.setItem(_,this.sessionId),this._debug&&this._log("newSession",{sessionId:this.sessionId});}_log(e,t){if(!this._debug||typeof console>"u")return;let n=new Date().toISOString().slice(11,23);t?console.log(`%c[GL ${n}]%c ${e}`,"color:#10b981;font-weight:bold","color:inherit",t):console.log(`%c[GL ${n}]%c ${e}`,"color:#10b981;font-weight:bold","color:inherit");}setSessionId(e){this.sessionId=e,typeof sessionStorage<"u"&&sessionStorage.setItem(_,e);}setRelease(e){this.release=e;}getRelease(){return this.release}setEnvironment(e){this.environment=e;}getEnvironment(){return this.environment}setUser(e){this.identify(e.id),this.userProperties={...e},this.flagClient&&this.flagClient.setUser(e.id,this.userProperties);}getUser(){return {...this.userProperties}}isEnabled(e,t=false,n){return this.flagClient?this.flagClient.isEnabled(e,t,n):t}getVariant(e,t,n){return this.flagClient?this.flagClient.getVariant(e,t,n):t}getAllFlags(){return this.flagClient?this.flagClient.getAllFlags():{}}onFlagChange(e,t){return this.flagClient?this.flagClient.onFlagChange(e,t):()=>{}}flagsReady(){return this.flagClient?this.flagClient.onReady():Promise.resolve()}track(e,t){if(this.disabled)return;let{distinctId:n,...r}=t??{},i={event:e,distinctId:n??this.anonymousId,properties:{...Y(),...r,$session_id:this.sessionId,...this.release?{$release:this.release}:{},$environment:this.environment},timestamp:new Date().toISOString()};this.eventBuffer.push(i),this._debug&&this._log("track",{event:e,sessionId:this.sessionId}),this.eventBuffer.length>=this.batchSize&&this.flush();}addBreadcrumb(e){if(this.disabled)return;let t={ts:e.ts??new Date().toISOString(),...e};this.breadcrumbBuffer.push(t),this.breadcrumbBuffer.length>T.MAX_BREADCRUMBS&&this.breadcrumbBuffer.shift();}captureException(e,t){if(this.disabled)return;let n=this.buildErrorEntry(e,t);if(this.beforeSend){try{n=this.beforeSend(n);}catch{n=null;}if(!n)return}this._debug&&this._log("captureException",{message:n.message,type:n.exception_type,sessionId:this.sessionId,traceId:n.trace_id}),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(e,t){if(this.disabled)return;let n={level:t?.level??"info",message:e,platform:typeof document<"u"?"browser":"node",frames:[],breadcrumbs:this.breadcrumbBuffer.slice(),fingerprint:t?.fingerprint,tags:{session_id:this.sessionId,...t?.tags},extra:t?.extra,user_id:t?.user_id??this.anonymousId,timestamp:new Date().toISOString()};this.useEnvelope?(this.errorBuffer.push(n),this.errorBuffer.length>=this.batchSize&&this.flush()):this.warn(e);}buildErrorEntry(e,t){let n,r,i=[];if(e instanceof Error)n=e.name,r=e.message,i=ae(e.stack);else if(typeof e=="string")r=e;else try{r=JSON.stringify(e);}catch{r=String(e);}return {level:t?.level??"error",platform:typeof document<"u"?"browser":"node",exception_type:n,message:r,frames:i,breadcrumbs:this.breadcrumbBuffer.slice(),fingerprint:t?.fingerprint,tags:{session_id:this.sessionId,...t?.tags},extra:t?.extra,user_id:t?.user_id??this.anonymousId,timestamp:new Date().toISOString(),trace_id:this.navTransaction?.trace_id,span_id:this.navTransaction?.span_id,release:this.release??void 0,environment:this.environment}}captureVital(e,t,n){if(this.disabled||!Number.isFinite(t)||t<0)return;let r=n?.rating??oe(e,t),i={metric:e,value_ms:e==="cls"?t:Math.round(t),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(i),this.vitalBuffer.length>=this.batchSize&&this.flush()):this.track("$web_vital",{properties:{$metric:e.toUpperCase(),$value_ms:i.value_ms,$rating:r}});}startTransaction(e){return this.makeSpan(void 0,e)}startSpan(e){return this.makeSpan(void 0,e)}makeSpan(e,t){let n=t?.trace_id??t?.parent?.trace_id??e?.trace_id??ie(),r=se(),i=t?.parent?.span_id??e?.span_id,o=Date.now(),a=new Date(o).toISOString(),l={...t?.attributes??{}},u="unset",d=[],c=false,f=this,g={span_id:r,trace_id:n,setAttribute(h,p){l[h]=p;},setStatus(h){u=h;},addEvent(h,p){d.push({ts:new Date().toISOString(),name:h,attributes:p});},startChild(h){return f.makeSpan(g,h)},finish(){if(c)return;c=true;let h=Date.now(),p={span_id:r,trace_id:n,parent_span_id:i,name:t?.name,op:t?.op,status:u==="unset"?"ok":u,kind:t?.kind,attributes:l,events:d,start_time:a,end_time:new Date(h).toISOString(),timestamp:a,duration_ms:h-o};f.useEnvelope&&(f.spanBuffer.push(p),f.spanBuffer.length>=f.batchSize&&f.flush());}};return g}async flush(){let e=this.logBuffer.splice(0),t=this.eventBuffer.splice(0),n=this.errorBuffer.splice(0),r=this.vitalBuffer.splice(0),i=this.spanBuffer.splice(0);this._debug&&(e.length||t.length||n.length||r.length||i.length)&&this._log("flush",{logs:e.length,events:t.length,errors:n.length,vitals:r.length,spans:i.length});let o=[];this.useEnvelope?(e.length>0||t.length>0||n.length>0||r.length>0||i.length>0)&&o.push(this.sendEnvelope(e,t,n,r,i)):(e.length>0&&o.push(this.sendLogs(e)),t.length>0&&o.push(this.sendEvents(t))),await Promise.all(o);}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(e){for(let n=0;n<e.length;n+=500){let i=e.slice(n,n+500).map(o=>({severity:o.severity,message:o.message,properties:o.properties,timestamp:o.timestamp}));await this.postWithRetry("/v1/logs",i,o=>{for(let a of o)this.logBuffer.push({severity:a.severity,message:a.message,properties:a.properties,timestamp:a.timestamp});});}}async sendEvents(e){for(let n=0;n<e.length;n+=500){let i=e.slice(n,n+500).map(o=>({event:o.event,distinctId:o.distinctId,properties:o.properties,timestamp:o.timestamp}));await this.postWithRetry("/v1/events",i,o=>{for(let a of o)this.eventBuffer.push({event:a.event,distinctId:a.distinctId,properties:a.properties,timestamp:a.timestamp});});}}async sendEnvelope(e,t,n,r,i){let a=[...e.map(l=>({kind:"log",entry:l})),...t.map(l=>({kind:"event",entry:l})),...n.map(l=>({kind:"error",entry:l})),...r.map(l=>({kind:"vital",entry:l})),...i.map(l=>({kind:"span",entry:l}))];for(let l=0;l<a.length;l+=1e3){let u=a.slice(l,l+1e3),d=JSON.stringify({v:1,sdk:`js@${v}`,sent_at:new Date().toISOString()}),c=u.map(g=>{if(g.kind==="log"){let p=g.entry;return JSON.stringify({type:"log",severity:p.severity,message:p.message,properties:p.properties,timestamp:p.timestamp})}if(g.kind==="event"){let p=g.entry;return JSON.stringify({type:"event",event:p.event,distinctId:p.distinctId,properties:p.properties,timestamp:p.timestamp})}if(g.kind==="error"){let p=g.entry;return JSON.stringify({type:"error",...p})}if(g.kind==="vital"){let p=g.entry;return JSON.stringify({type:"vital",...p})}let h=g.entry;return JSON.stringify({type:"span",...h})}),f=[d,...c].join(`
|
|
6
|
+
`);await this.postEnvelopeWithRetry(f,u);}}async postEnvelopeWithRetry(e,t,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:e});if(r.status===429||r.status===503){if(n<4){let i=Math.min(1e3*Math.pow(2,n),8e3),o=Math.random()*500;return await new Promise(a=>setTimeout(a,i+o)),this.postEnvelopeWithRetry(e,t,n+1)}this.onError(new Error(`GoodLogs rate limited after ${n} retries`));return}if(!r.ok){let i=await r.text().catch(()=>"");if(this.onError(new Error(`GoodLogs envelope error ${r.status}: ${i}`)),r.status>=500&&n===0)for(let o of t)o.kind==="log"?this.logBuffer.push(o.entry):o.kind==="event"?this.eventBuffer.push(o.entry):o.kind==="error"?this.errorBuffer.push(o.entry):o.kind==="vital"?this.vitalBuffer.push(o.entry):this.spanBuffer.push(o.entry);}}catch(r){if(n===0)for(let i of t)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);this.onError(r instanceof Error?r:new Error(String(r)));}}async postWithRetry(e,t,n,r=0){try{let i=await fetch(`${this.endpoint}${e}`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,"X-GoodLogs-SDK":`js/${v}`},body:JSON.stringify({batch:t})});if(i.status===429||i.status===503){if(r<4){let a=Math.min(1e3*Math.pow(2,r),8e3),l=Math.random()*500;return await new Promise(u=>setTimeout(u,a+l)),this.postWithRetry(e,t,n,r+1)}this.onError(new Error(`GoodLogs rate limited after ${r} retries`));return}if(!i.ok){let a=await i.text().catch(()=>""),l=new Error(`GoodLogs API error ${i.status}: ${a}`);this.onError(l),i.status>=500&&r===0&&n(t);return}let o=await i.json().catch(()=>null);if(o&&o.rejected&&o.rejected>0){let a=t.slice(o.accepted??0);a.length>0&&n(a);}}catch(i){let o=i instanceof Error?i:new Error(String(i));r===0&&n(t),this.onError(o);}}startTimer(){this.timer=setInterval(()=>{this.flush();},this.flushInterval);let e=this.timer;typeof e?.unref=="function"&&e.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 e=(t,n)=>{if(this.useEnvelope)this.captureVital(t.toLowerCase(),n);else {let r=t==="CLS"?"$value":"$value_ms";this.track("$web_vital",{properties:{$metric:t,[r]:t==="CLS"?n:Math.round(n)}});}};try{new PerformanceObserver(t=>{let n=t.getEntries()[0];n&&e("FCP",n.startTime);}).observe({type:"paint",buffered:!0});}catch{}try{new PerformanceObserver(t=>{let n=t.getEntries(),r=n[n.length-1];r&&e("LCP",r.startTime);}).observe({type:"largest-contentful-paint",buffered:!0});}catch{}try{let t=0;if(new PerformanceObserver(n=>{for(let r of n.getEntries())r.hadRecentInput||(t+=r.value);}).observe({type:"layout-shift",buffered:!0}),typeof document<"u"){let n=()=>{t>0&&e("CLS",Math.round(t*1e3)/1e3);};document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&n();});}}catch{}try{new PerformanceObserver(t=>{for(let n of t.getEntries()){let r=n;r.responseStart&&r.responseStart>0&&e("TTFB",r.responseStart);let i=c=>c&&Number.isFinite(c)&&c>0?c:0,o=i(r.domainLookupEnd)-i(r.domainLookupStart);o>0&&this.captureVital("dns",o);let a=i(r.connectEnd)-i(r.connectStart);a>0&&this.captureVital("tcp",a);let l=i(r.responseEnd)-i(r.responseStart);l>0&&this.captureVital("download",l);let u=i(r.domComplete)-i(r.responseEnd);u>0&&this.captureVital("dom_processing",u);let d=i(r.loadEventEnd)-i(r.fetchStart);d>0&&this.captureVital("page_load",d);}}).observe({type:"navigation",buffered:!0});}catch{try{if(typeof performance<"u"){let t=performance.getEntriesByType?.("navigation")?.[0];t?.responseStart&&e("TTFB",t.responseStart);let n=u=>u&&Number.isFinite(u)&&u>0?u:0,r=n(t?.domainLookupEnd)-n(t?.domainLookupStart);r>0&&this.captureVital("dns",r);let i=n(t?.connectEnd)-n(t?.connectStart);i>0&&this.captureVital("tcp",i);let o=n(t?.responseEnd)-n(t?.responseStart);o>0&&this.captureVital("download",o);let a=n(t?.domComplete)-n(t?.responseEnd);a>0&&this.captureVital("dom_processing",a);let l=n(t?.loadEventEnd)-n(t?.fetchStart);l>0&&this.captureVital("page_load",l);}}catch{}}try{new PerformanceObserver(t=>{for(let n of t.getEntries()){let r=n.duration;r>0&&e("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 e=(t="push")=>{typeof location<"u"&&location.pathname!==this.lastPath&&(this.lastPath=location.pathname,this.track("$pageview"),this.startNavTransaction(this.lastPath,t));};if(typeof history<"u"){let t=history.pushState,n=history.replaceState;history.pushState=function(...r){t.apply(this,r),e("push");},history.replaceState=function(...r){n.apply(this,r),e("replace");};}if(typeof addEventListener<"u"&&addEventListener("popstate",()=>e("popstate")),typeof document<"u"){let t=0,n=0,r=null;document.addEventListener("click",i=>{let a=i?.target;if(!a)return;let l=Date.now(),u=`${(a.tagName??"unknown").toLowerCase()}${a.id?"#"+a.id:""}${a.className&&typeof a.className=="string"?"."+a.className.trim().split(/\s+/).slice(0,2).join("."):""}`.slice(0,100);if(r===a&&l-t<1e3?(n++,n===3&&this.track("$rage_click",{$element:u,$tag:(a.tagName??"").toLowerCase(),$text:(a.textContent??"").slice(0,50).trim(),$url:typeof location<"u"?location.pathname:void 0})):n=1,r=a,t=l,!a.closest?.("a, button, input, select, textarea, [role=button], [onclick]")){let c=typeof location<"u"?location.pathname:"";setTimeout(()=>{(typeof location<"u"?location.pathname:"")===c&&this.track("$dead_click",{$element:u,$tag:(a.tagName??"").toLowerCase(),$text:(a.textContent??"").slice(0,50).trim(),$url:typeof location<"u"?location.pathname:void 0});},500);}},{capture:true,passive:true});}}startNavTransaction(e,t){try{this.navTransaction&&(this.navTransaction.finish(),this.navTransaction=null),this.navTransaction=this.startTransaction({op:"navigation",name:e,attributes:{"navigation.type":t,"http.url":typeof location<"u"?location.href:e}});let n=this.navTransaction;setTimeout(()=>{this.navTransaction===n&&(n.finish(),this.navTransaction=null);},3e4);}catch{}}attachGlobalErrorHandlers(){let e=globalThis;typeof e.addEventListener=="function"&&(this.errorHandler||this.rejectionHandler||(this.errorHandler=t=>{let n=t,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=t=>{let r=t.reason,i=r;if(!(r instanceof Error)){let o;if(typeof r=="string")o=r;else try{o=JSON.stringify(r);}catch{o=String(r);}i=new Error(o);}try{this.captureException(i,{tags:{source:"unhandledrejection"}});}catch{}},e.addEventListener("error",this.errorHandler),e.addEventListener("unhandledrejection",this.rejectionHandler)));}detachGlobalErrorHandlers(){let e=globalThis;typeof e.removeEventListener=="function"&&(this.errorHandler&&(e.removeEventListener("error",this.errorHandler),this.errorHandler=null),this.rejectionHandler&&(e.removeEventListener("unhandledrejection",this.rejectionHandler),this.rejectionHandler=null));}attachAutoBreadcrumbs(){if(typeof console<"u"){let e=this,t=["error","warn","info","log"];for(let n of t){let r=console[n];r&&(console[n]=function(...i){try{e.addBreadcrumb({category:"console",message:i.map(o=>typeof o=="string"?o:JSON.stringify(o)).join(" ").slice(0,500),level:n==="error"?"error":n==="warn"?"warning":"info"});}catch{}return r.apply(console,i)});}}if(typeof globalThis<"u"&&typeof globalThis.history<"u"){let e=this,t=globalThis,n=t.history.pushState;t.history.pushState=function(...r){try{e.addBreadcrumb({category:"navigation",message:`\u2192 ${String(r[2]??"")}`,level:"info"});}catch{}return n.apply(t.history,r)},t.addEventListener("popstate",()=>{try{e.addBreadcrumb({category:"navigation",message:`\u2190 ${t.location.pathname}`,level:"info"});}catch{}});}}attachFetchInstrumentation(){if(typeof fetch>"u")return;let e=globalThis;if(this.originalFetch)return;this.originalFetch=e.fetch;let t=e.fetch.bind(globalThis),n=this;e.fetch=function(i,o){let a="",l="GET";if(typeof i=="string")a=i;else if(i&&typeof i=="object"){let c=i;a=c.url??"",l=c.method??l;}let u=o??{};if(u.method?l=String(u.method).toUpperCase():typeof i=="object"&&(l=i.method?.toUpperCase()??l),a.startsWith(n.endpoint))return t(i,u);let d=n.startSpan({op:"http.client",name:`${l} ${a}`,attributes:{"http.method":l,"http.url":a},parent:n.navTransaction??void 0});try{let c=`00-${d.trace_id}-${d.span_id}-01`,f={...u},g=f.headers??{};return f.headers={...g,traceparent:c},t(i,f).then(h=>{let p=h;return typeof p.status=="number"&&d.setAttribute("http.status_code",p.status),d.setStatus(p.ok===!1?"error":"ok"),d.finish(),h}).catch(h=>{throw d.setStatus("error"),d.setAttribute("error.message",h instanceof Error?h.message:String(h)),d.finish(),h})}catch(c){throw d.setStatus("error"),d.finish(),c}};}detachFetchInstrumentation(){this.originalFetch&&(globalThis.fetch=this.originalFetch,this.originalFetch=null);}attachXhrInstrumentation(){let t=globalThis.XMLHttpRequest;if(!t||!t.prototype)return;let n=Symbol.for("goodlogs.xhr.patched"),r=t.prototype;if(r[n]){this.xhrPatched=true;return}let i=r.open,o=r.setRequestHeader,a=r.send,l=this;r.open=function(d,c,...f){return this.__gl_method=typeof d=="string"?d.toUpperCase():"GET",this.__gl_url=typeof c=="string"?c:String(c??""),this.__gl_headers_set=false,i.apply(this,[d,c,...f])},r.setRequestHeader=function(d,c){return this.__gl_headers_set=true,o.apply(this,[d,c])},r.send=function(d){let c=this.__gl_url||"",f=this.__gl_method||"GET";if(c.startsWith(l.endpoint))return a.apply(this,[d]);let g=l.startSpan({op:"http.client",name:`${f} ${c}`,attributes:{"http.method":f,"http.url":c},parent:l.navTransaction??void 0});try{let m=`00-${g.trace_id}-${g.span_id}-01`;o.apply(this,["traceparent",m]);}catch{}let h=(m,S,F)=>{m&&g.setAttribute("http.status_code",m),F&&g.setAttribute("error.message",F),g.setStatus(S?"ok":"error"),g.finish();},p=this.addEventListener;return typeof p=="function"?(p.call(this,"load",()=>{let m=Number(this.status||0);h(m,m>0&&m<500);}),p.call(this,"error",()=>h(0,false,"network error")),p.call(this,"abort",()=>h(0,false,"aborted")),p.call(this,"timeout",()=>h(0,false,"timeout"))):h(0,true),a.apply(this,[d])},r[n]=true,r.__gl_orig_open=i,r.__gl_orig_set_header=o,r.__gl_orig_send=a,this.xhrPatched=true;}detachXhrInstrumentation(){if(!this.xhrPatched)return;let t=globalThis.XMLHttpRequest?.prototype;if(!t)return;let n=Symbol.for("goodlogs.xhr.patched");t.__gl_orig_open&&(t.open=t.__gl_orig_open),t.__gl_orig_set_header&&(t.setRequestHeader=t.__gl_orig_set_header),t.__gl_orig_send&&(t.send=t.__gl_orig_send),delete t.__gl_orig_open,delete t.__gl_orig_set_header,delete t.__gl_orig_send,delete t[n],this.xhrPatched=false;}attachClickCapture(){typeof document>"u"||(this.clickHandler=e=>{let t=e,n=t.target?.closest?.("a, button, [data-gl-event], [role='button']");if(!n)return;let r=n.getAttribute?.("data-gl-event"),i=n.tagName?.toLowerCase()??"",o=(n.textContent??"").trim().slice(0,50),a=n.getAttribute?.("href")??void 0,l=(n.className??"").toString().slice(0,80),u=globalThis,d=u.innerWidth,c=u.innerHeight,f=u.scrollY,g=typeof document<"u"?document.documentElement?.scrollHeight:void 0;this.track(r||"$click",{$element_tag:i,$element_id:n.id||void 0,$element_text:o||void 0,$element_href:a,$element_classes:l||void 0,$element_selector:te(n),$click_x:t.clientX,$click_y:t.clientY,$page_x:t.pageX,$page_y:t.pageY,$viewport_w:d,$viewport_h:c,$scroll_y:f,$doc_h:g,$url:typeof location<"u"?location.href:void 0,$pathname:typeof location<"u"?location.pathname: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 e=this.logBuffer.splice(0),t=this.eventBuffer.splice(0),n={"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,"X-GoodLogs-SDK":`js/${v}`};e.length>0&&fetch(`${this.endpoint}/v1/logs`,{method:"POST",headers:n,body:JSON.stringify({batch:e.map(r=>({severity:r.severity,message:r.message,properties:r.properties,timestamp:r.timestamp}))}),keepalive:true}).catch(()=>{}),t.length>0&&fetch(`${this.endpoint}/v1/events`,{method:"POST",headers:n,body:JSON.stringify({batch:t.map(r=>({event:r.event,distinctId:r.distinctId,properties:r.properties,timestamp:r.timestamp}))}),keepalive:true}).catch(()=>{});}sendTelemetry(e,t,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:e,level:t,metadata:{...n,sdk_version:v}}),keepalive:true}).catch(()=>{});}};T.MAX_BREADCRUMBS=50;var L=T;var A=class{constructor(e){if(!e.apiKey)throw new Error("apiKey is required");if(!e.apiKey.startsWith("gl_sk_"))throw new Error("GoodLogsClient requires a secret API key (gl_sk_...)");this.apiKey=e.apiKey,this.endpoint=y(e.apiKey,e.endpoint),this.timeout=e.timeout??3e4,this.alerts=new P(this),this.slos=new N(this),this.ai=new B(this);}async _request(e,t,n){let r=`${this.endpoint}${t}`,i={Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json"},o=new AbortController,a=setTimeout(()=>o.abort(),this.timeout);try{let l=await fetch(r,{method:e,headers:i,body:n?JSON.stringify(n):void 0,signal:o.signal});if(!l.ok){let u=await l.json().catch(()=>({})),d=u?.error?.message??`API error ${l.status}`;throw new I(l.status,d,u?.error?.code)}return l.status===204?void 0:await l.json()}finally{clearTimeout(a);}}_get(e){return this._request("GET",e)}_post(e,t){return this._request("POST",e,t)}_put(e,t){return this._request("PUT",e,t)}_delete(e){return this._request("DELETE",e)}info(){return this._get("/v1/info")}schema(){return this._get("/v1/schema")}gql(e){return this._post("/v1/gql/query",{q:e})}gqlBatch(e){return this._post("/v1/gql",{queries:e})}gqlAutocomplete(e,t){let n=`/v1/gql/autocomplete?q=${encodeURIComponent(e)}`;return t!==void 0&&(n+=`&cursor=${t}`),this._get(n)}nl2gql(e,t){return this._post("/v1/gql/nl",{prompt:e,mode:t})}},P=class{constructor(e){this.client=e;}list(){return this.client._get("/v1/alerts")}create(e){return this.client._post("/v1/alerts",e)}update(e,t){return this.client._put(`/v1/alerts/${e}`,t)}delete(e){return this.client._delete(`/v1/alerts/${e}`)}mute(e,t){return this.client._post(`/v1/alerts/${e}/mute`,{minutes:t})}},N=class{constructor(e){this.client=e;}list(){return this.client._get("/v1/slos")}create(e){return this.client._post("/v1/slos",e)}update(e,t){return this.client._put(`/v1/slos/${e}`,t)}delete(e){return this.client._delete(`/v1/slos/${e}`)}},B=class{constructor(e){this.client=e;}chat(e,t){return this.client._post("/v1/ai/chat",{message:e,session_id:t})}},I=class extends Error{constructor(t,n,r){super(n);this.status=t;this.code=r;this.name="GoodLogsApiError";}};var G="0.1.0";function le(s,e){let t=y(e?.apiKey??"",e?.endpoint).replace(/\/+$/,""),n={"Content-Type":"application/json","X-GoodLogs-SDK":G};e?.token&&(n.Authorization=`Bearer ${e.token}`),fetch(`${t}/v1/telemetry`,{method:"POST",headers:n,body:JSON.stringify({source:s.source,event:s.event,level:s.level??"info",metadata:{...s.metadata,sdk_version:G}}),keepalive:true}).catch(()=>{});}function x(s){if(!s)return null;let e=s.trim().split("-");if(e.length!==4)return null;let[t,n,r,i]=e;return t.length!==2||n.length!==32||r.length!==16||i.length!==2||!/^[0-9a-f]+$/.test(n)||!/^[0-9a-f]+$/.test(r)?null:{trace_id:n,parent_span_id:r}}function O(s,e){if(!s)return;let t=s[e]??s[e.toLowerCase()];return Array.isArray(t)?t[0]:t}function ue(s){return function(t,n,r){let i=(t.method??"GET").toUpperCase(),o=t.originalUrl??t.url??"",a=x(O(t.headers,"traceparent")),l=s.startTransaction({op:"http.server",name:`${i} ${o}`,trace_id:a?.trace_id,attributes:{"http.method":i,"http.url":o}}),u=false,d=()=>{if(u)return;u=true;let c=t.route?.path;c&&l.setAttribute("http.route",c);let f=n.statusCode??200;l.setAttribute("http.status_code",f),l.setStatus(f>=500?"error":"ok"),l.finish();};n.on("finish",d),n.on("close",d),t.goodlogs={span:l},r();}}function de(s){return function(t,n,r){t.addHook("onRequest",(i,o,a)=>{let l=(i.method??"GET").toUpperCase(),u=i.url??"",d=x(O(i.headers,"traceparent")),c=s.startTransaction({op:"http.server",name:`${l} ${u}`,trace_id:d?.trace_id,attributes:{"http.method":l,"http.url":u}});i.__goodlogsSpan=c,a();}),t.addHook("onResponse",(i,o,a)=>{let l=i.__goodlogsSpan;if(l){let u=i.routerPath??i.routeOptions?.url;u&&l.setAttribute("http.route",u);let d=o.statusCode??o.raw?.statusCode??200;l.setAttribute("http.status_code",d),l.setStatus(d>=500?"error":"ok"),l.finish();}a();}),r();}}function ce(s){return {intercept(e,t){let n=e.switchToHttp(),r=n.getRequest(),i=n.getResponse(),o=(r.method??"GET").toUpperCase(),a=r.originalUrl??r.url??"",l=x(O(r.headers,"traceparent")),u=s.startTransaction({op:"http.server",name:`${o} ${a}`,trace_id:l?.trace_id,attributes:{"http.method":o,"http.url":a}}),d=false,c=(g,h)=>{if(d)return;d=true;let p=r.route?.path;p&&u.setAttribute("http.route",p);let m=g??i.statusCode??200;u.setAttribute("http.status_code",m),u.setStatus(h||m>=500?"error":"ok"),u.finish();};i.on("finish",()=>c()),i.on("close",()=>c());let f=t.handle();if(f&&typeof f.subscribe=="function"){let g=f.subscribe({next:()=>{},error:h=>{u.setAttribute("error.message",h instanceof Error?h.message:String(h)),c(500,true);},complete:()=>c()});return {unsubscribe:()=>g.unsubscribe?.()}}return f}}}function pe(s){let e=globalThis.process;if(!e||typeof e.on!="function")return;let t=e,n=Symbol.for("goodlogs.node-process.patched");t[n]||(e.on("uncaughtException",r=>{try{s.captureException(r instanceof Error?r:new Error(String(r)),{tags:{source:"uncaughtException"},level:"fatal"}),s.flush();}catch{}}),e.on("unhandledRejection",r=>{try{let i=r instanceof Error?r:new Error(typeof r=="string"?r:(()=>{try{return JSON.stringify(r)}catch{return String(r)}})());s.captureException(i,{tags:{source:"unhandledRejection"}});}catch{}}),t[n]=true);}var M=globalThis.URL;function E(s){return !!M&&s instanceof M}var U=Symbol.for("goodlogs.node-http.patched");function fe(...s){let e=s[0],t=s[1],n="GET",r="";if(typeof e=="string")r=e,t&&typeof t=="object"&&!E(t)&&(n=String(t.method??n).toUpperCase());else if(E(e))r=e.toString(),t&&typeof t=="object"&&!E(t)&&(n=String(t.method??n).toUpperCase());else if(e&&typeof e=="object"){let o=e;n=String(o.method??n).toUpperCase();let a=(o.protocol??"http:").replace(":",""),l=o.hostname??o.host??"localhost",u=o.port?`:${o.port}`:"";r=`${a}://${l}${u}${o.path??"/"}`;}return {method:n,url:r,isOurs:o=>!!o&&r.startsWith(o)}}function he(s,e,t){let n=s[0]&&typeof s[0]=="object"&&!E(s[0])?s[0]:s[1]&&typeof s[1]=="object"&&!E(s[1])?s[1]:void 0;n&&(n.headers||(n.headers={}),!(e in n.headers)&&!(e.toLowerCase()in n.headers)&&(n.headers[e]=t));}function ge(s,e){let t=e?.endpoint??s.endpoint??"",n=r=>{let i=r;if(i[U])return;i[U]=true;let o=r.request.bind(r);r.request=function(...l){let{method:u,url:d,isOurs:c}=fe(...l);if(!d||c(t))return o(...l);let f=s.startTransaction({op:"http.client",name:`${u} ${d}`,attributes:{"http.method":u,"http.url":d}});he(l,"traceparent",`00-${f.trace_id}-${f.span_id}-01`);let g=false,h=(m,S)=>{g||(g=true,typeof m=="number"&&f.setAttribute("http.status_code",m),S?(f.setAttribute("error.message",S.message),f.setStatus("error")):f.setStatus(typeof m=="number"&&m>=500?"error":"ok"),f.finish());},p=o(...l);return p.on("response",m=>h(m.statusCode)),p.on("error",m=>h(void 0,m)),p.on("close",()=>h()),p};};if(typeof R=="function"){try{let r=R("http");n(r);}catch{}try{let r=R("https");n(r);}catch{}}}
|
|
7
|
+
export{w as FlagClient,L as GoodLogs,I as GoodLogsApiError,A as GoodLogsClient,ue as goodlogsExpress,de as goodlogsFastify,ce as goodlogsNestInterceptor,ge as instrumentNodeHttp,pe as instrumentNodeProcess,x as parseTraceparent,y as resolveEndpoint,H as resolveRegion,le as sendTelemetry};
|
package/dist/memory.d.cts
CHANGED
package/dist/memory.d.ts
CHANGED
package/dist/profiling.d.cts
CHANGED
package/dist/profiling.d.ts
CHANGED
package/dist/react.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var react=require('react');var
|
|
1
|
+
'use strict';var react=require('react');var l=react.createContext({parent:null,depth:0}),s=null,c=[],d=null,v=3e3,C=200,y=.1;function p(){d||(d=setInterval(m,v),typeof window<"u"&&window.addEventListener("beforeunload",()=>m()));}function m(){if(!s||c.length===0)return;let t=c;c=[];let n=s.endpoint,e=s.apiKey;try{fetch(`${n}/v1/profiles/renders`,{method:"POST",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify({batch:t}),keepalive:!0}).catch(()=>{});}catch{}}function _(){return typeof window>"u"?null:window.location?.pathname??null}function R(t,n,e){return (o,i,r,u,L,w)=>{r<y||(c.push({component:t||o,phase:i,actual_ms:Math.round(r*100)/100,base_ms:Math.round(u*100)/100,commit_time:Math.round(w*100)/100,route:_(),timestamp:new Date().toISOString(),parent:n,depth:e}),c.length>=C&&m());}}function k(t){s=t,p();}function E({gl:t,id:n,children:e}){t&&!s&&(s=t,p()),s&&!d&&p();let o=react.useContext(l),i={parent:n,depth:o.depth+1};return react.createElement(l.Provider,{value:i},react.createElement(react.Profiler,{id:n,onRender:R(n,o.parent,o.depth)},e))}function F(t,n){let e=n||t.displayName||t.name||"Unknown",o=i=>{let r=react.useContext(l),u={parent:e,depth:r.depth+1};return react.createElement(l.Provider,{value:u},react.createElement(react.Profiler,{id:e,onRender:R(e,r.parent,r.depth)},react.createElement(t,i)))};return o.displayName=`withProfiler(${e})`,o}function N(t,n,e=false){let[o,i]=react.useState(()=>t.isEnabled(n,e)),r=react.useRef(t);return react.useEffect(()=>(i(r.current.isEnabled(n,e)),r.current.onFlagChange(n,()=>{i(r.current.isEnabled(n,e));})),[n,e]),o}function G(t,n,e){let[o,i]=react.useState(()=>t.getVariant(n,e)),r=react.useRef(t);return react.useEffect(()=>(i(r.current.getVariant(n,e)),r.current.onFlagChange(n,()=>{i(r.current.getVariant(n,e));})),[n,e]),o}exports.GoodLogsProfiler=E;exports.initReactProfiler=k;exports.useFeatureFlag=N;exports.useVariant=G;exports.withProfiler=F;
|
package/dist/react.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode, ComponentType, FC } from 'react';
|
|
2
|
-
import { G as GoodLogs } from './client-
|
|
2
|
+
import { G as GoodLogs } from './client-D5LyyDBY.cjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* React Profiler Integration — component render timing.
|
|
@@ -38,5 +38,23 @@ declare function GoodLogsProfiler({ gl, id, children, }: {
|
|
|
38
38
|
* HOC: wraps a component with React.Profiler + parent-child context.
|
|
39
39
|
*/
|
|
40
40
|
declare function withProfiler<P extends Record<string, unknown>>(Component: ComponentType<P>, displayName?: string): FC<P>;
|
|
41
|
+
/**
|
|
42
|
+
* React hook for boolean feature flags.
|
|
43
|
+
*
|
|
44
|
+
* Usage:
|
|
45
|
+
* const enabled = useFeatureFlag(gl, "new-checkout");
|
|
46
|
+
* if (enabled) return <NewCheckout />;
|
|
47
|
+
*
|
|
48
|
+
* Re-renders when the flag value changes (on next poll).
|
|
49
|
+
*/
|
|
50
|
+
declare function useFeatureFlag(gl: GoodLogs, flagKey: string, defaultValue?: boolean): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* React hook for multivariate feature flags.
|
|
53
|
+
*
|
|
54
|
+
* Usage:
|
|
55
|
+
* const theme = useVariant(gl, "theme", "light");
|
|
56
|
+
* return <App theme={theme} />;
|
|
57
|
+
*/
|
|
58
|
+
declare function useVariant<T = unknown>(gl: GoodLogs, flagKey: string, defaultValue: T): T;
|
|
41
59
|
|
|
42
|
-
export { GoodLogsProfiler, initReactProfiler, withProfiler };
|
|
60
|
+
export { GoodLogsProfiler, initReactProfiler, useFeatureFlag, useVariant, withProfiler };
|
package/dist/react.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode, ComponentType, FC } from 'react';
|
|
2
|
-
import { G as GoodLogs } from './client-
|
|
2
|
+
import { G as GoodLogs } from './client-D5LyyDBY.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* React Profiler Integration — component render timing.
|
|
@@ -38,5 +38,23 @@ declare function GoodLogsProfiler({ gl, id, children, }: {
|
|
|
38
38
|
* HOC: wraps a component with React.Profiler + parent-child context.
|
|
39
39
|
*/
|
|
40
40
|
declare function withProfiler<P extends Record<string, unknown>>(Component: ComponentType<P>, displayName?: string): FC<P>;
|
|
41
|
+
/**
|
|
42
|
+
* React hook for boolean feature flags.
|
|
43
|
+
*
|
|
44
|
+
* Usage:
|
|
45
|
+
* const enabled = useFeatureFlag(gl, "new-checkout");
|
|
46
|
+
* if (enabled) return <NewCheckout />;
|
|
47
|
+
*
|
|
48
|
+
* Re-renders when the flag value changes (on next poll).
|
|
49
|
+
*/
|
|
50
|
+
declare function useFeatureFlag(gl: GoodLogs, flagKey: string, defaultValue?: boolean): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* React hook for multivariate feature flags.
|
|
53
|
+
*
|
|
54
|
+
* Usage:
|
|
55
|
+
* const theme = useVariant(gl, "theme", "light");
|
|
56
|
+
* return <App theme={theme} />;
|
|
57
|
+
*/
|
|
58
|
+
declare function useVariant<T = unknown>(gl: GoodLogs, flagKey: string, defaultValue: T): T;
|
|
41
59
|
|
|
42
|
-
export { GoodLogsProfiler, initReactProfiler, withProfiler };
|
|
60
|
+
export { GoodLogsProfiler, initReactProfiler, useFeatureFlag, useVariant, withProfiler };
|
package/dist/react.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {createContext,useContext,createElement,Profiler}from'react';var
|
|
1
|
+
import {createContext,useContext,createElement,Profiler,useState,useRef,useEffect}from'react';var l=createContext({parent:null,depth:0}),s=null,c=[],d=null,v=3e3,C=200,y=.1;function p(){d||(d=setInterval(m,v),typeof window<"u"&&window.addEventListener("beforeunload",()=>m()));}function m(){if(!s||c.length===0)return;let t=c;c=[];let n=s.endpoint,e=s.apiKey;try{fetch(`${n}/v1/profiles/renders`,{method:"POST",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify({batch:t}),keepalive:!0}).catch(()=>{});}catch{}}function _(){return typeof window>"u"?null:window.location?.pathname??null}function R(t,n,e){return (o,i,r,u,L,w)=>{r<y||(c.push({component:t||o,phase:i,actual_ms:Math.round(r*100)/100,base_ms:Math.round(u*100)/100,commit_time:Math.round(w*100)/100,route:_(),timestamp:new Date().toISOString(),parent:n,depth:e}),c.length>=C&&m());}}function k(t){s=t,p();}function E({gl:t,id:n,children:e}){t&&!s&&(s=t,p()),s&&!d&&p();let o=useContext(l),i={parent:n,depth:o.depth+1};return createElement(l.Provider,{value:i},createElement(Profiler,{id:n,onRender:R(n,o.parent,o.depth)},e))}function F(t,n){let e=n||t.displayName||t.name||"Unknown",o=i=>{let r=useContext(l),u={parent:e,depth:r.depth+1};return createElement(l.Provider,{value:u},createElement(Profiler,{id:e,onRender:R(e,r.parent,r.depth)},createElement(t,i)))};return o.displayName=`withProfiler(${e})`,o}function N(t,n,e=false){let[o,i]=useState(()=>t.isEnabled(n,e)),r=useRef(t);return useEffect(()=>(i(r.current.isEnabled(n,e)),r.current.onFlagChange(n,()=>{i(r.current.isEnabled(n,e));})),[n,e]),o}function G(t,n,e){let[o,i]=useState(()=>t.getVariant(n,e)),r=useRef(t);return useEffect(()=>(i(r.current.getVariant(n,e)),r.current.onFlagChange(n,()=>{i(r.current.getVariant(n,e));})),[n,e]),o}export{E as GoodLogsProfiler,k as initReactProfiler,N as useFeatureFlag,G as useVariant,F as withProfiler};
|
package/dist/replay.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var
|
|
1
|
+
'use strict';var H=new Set([1,3,6]);function W(r){return r.every(n=>{if(n.type!==3)return false;let a=n.data?.source;return a!==void 0&&H.has(a)})}var k=null;async function Z(r,n={}){if(typeof document>"u")return null;if(k)return k;let a=n.sampleRate??1;if(a<1&&Math.random()>a)return null;let f=n.rrwebRecord??await Y();if(!f)return null;let d=r.endpoint,g=r.apiKey,m=r,K=n.debug??m._debug??false,i=(e,s)=>{if(!K||typeof console>"u")return;let t=new Date().toISOString().slice(11,23);s?console.log(`%c[GL:replay ${t}]%c ${e}`,"color:#f59e0b;font-weight:bold","color:inherit",s):console.log(`%c[GL:replay ${t}]%c ${e}`,"color:#f59e0b;font-weight:bold","color:inherit");},O=n.flushIntervalMs??5e3,B=n.flushBytes??5e5,b=n.sessionTimeoutMs??1800*1e3,h=n.maxSessionMs??3600*1e3;i("config",{flushIntervalMs:O,flushBytes:B,sessionTimeoutMs:b/1e3+"s",maxSessionMs:h/1e3+"s"});let o=m.sessionId,u=[],y=0,_=`gl_replay_seq_${o}`,x=(()=>{try{return parseInt(sessionStorage?.getItem(_)??"0",10)||0}catch{return 0}})(),$=()=>{try{sessionStorage?.setItem(_,String(x));}catch{}},R=false,w=false,l=Date.now(),c=Date.now(),E=null,C=()=>{i("session:announce",{sessionId:o,distinctId:m.getDistinctId()}),v(d,g,{session_id:o,distinct_id:m.getDistinctId(),started_at:new Date(c).toISOString(),start_url:typeof location<"u"?location.href:null,last_url:typeof location<"u"?location.href:null},n.onError);},L=()=>{let e=o;i("session:seal",{sessionId:e,queueSize:u.length}),p(true),v(d,g,{session_id:e,ended_at:new Date().toISOString()},n.onError);},p=async(e=false)=>{if(u.length===0)return;if(!e&&W(u)){u=[],y=0;return}let s=u,t=s[0].timestamp,M=s[s.length-1].timestamp,G=s.length,T=o;u=[],y=0;let U=x++;$();try{let I=JSON.stringify(s),F=await X(I);i("chunk:upload",{sessionId:T,seq:U,events:G,bytes:I.length,range:`${new Date(t).toISOString()} \u2192 ${new Date(M).toISOString()}`});let Q=`${d}/v1/replay/chunks?session_id=${encodeURIComponent(T)}&seq=${U}&start_ts=${encodeURIComponent(new Date(t).toISOString())}&end_ts=${encodeURIComponent(new Date(M).toISOString())}&event_count=${G}`;await fetch(Q,{method:"POST",headers:{Authorization:`Bearer ${g}`,"Content-Type":"application/gzip","Content-Encoding":"gzip"},body:F,keepalive:!0});}catch(I){n.onError?.(I);}v(d,g,{session_id:T,last_url:typeof location<"u"?location.href:null,last_activity_at:new Date(M).toISOString(),has_error:R||void 0},n.onError);},S=()=>{let e=Date.now()-c,s=Date.now()-l;i("session:rotate",{oldSessionId:o,elapsed:Math.round(e/1e3)+"s",idle:Math.round(s/1e3)+"s"}),L();try{E?.();}catch(t){n.onError?.(t);}m.newSession(),o=m.getSessionId(),x=0,_=`gl_replay_seq_${o}`,$(),R=false,l=Date.now(),c=Date.now(),C(),q();},D=false,q=()=>{E=f({emit:e=>{if(w)return;e.type===3&&H.has(e.data?.source??-1)||(l=Date.now());let t=Date.now();if(!D&&(t-c>h||t-l>b)){D=true,i("emit:session-expired",{elapsed:Math.round((t-c)/1e3)+"s",idle:Math.round((t-l)/1e3)+"s"}),S(),D=false;return}u.push(e),y+=256,y>=B&&p();},checkoutEveryNms:6e4,maskAllInputs:n.maskAllInputs??true,blockSelector:n.blockSelector??"[data-gl-block]",maskTextSelector:n.maskTextSelector??"[data-gl-mask]",sampling:{mousemove:50,mouseInteraction:true,scroll:150,input:"last"}});},N=setInterval(()=>{globalThis.__gl_replay_has_error__&&(R=true);},1e3),j=()=>{if(!w){i("stop",{sessionId:o}),w=true,clearInterval(J),clearInterval(V),clearInterval(N),document?.removeEventListener("visibilitychange",A),typeof window<"u"&&window.removeEventListener("beforeunload",P);try{E?.();}catch(e){n.onError?.(e);}L(),k=null;}};i("start",{sessionId:o,sampleRate:a}),C(),q();let J=setInterval(()=>{p();},O),V=setInterval(()=>{if(w)return;let e=Date.now();if(e-l>b){i("watchdog:idle-timeout",{idle:Math.round((e-l)/1e3)+"s"}),S();return}if(e-c>h){i("watchdog:max-duration",{elapsed:Math.round((e-c)/1e3)+"s"}),S();return}},1e4),A=()=>{if(!w){if(document?.visibilityState==="hidden")i("visibility:hidden",{sessionId:o}),p(true),v(d,g,{session_id:o,ended_at:new Date().toISOString()},n.onError);else if(document?.visibilityState==="visible"){let e=Date.now(),s=e-l,t=e-c;i("visibility:visible",{idle:Math.round(s/1e3)+"s",elapsed:Math.round(t/1e3)+"s"}),s>b||t>h?S():l=e;}}};document.addEventListener("visibilitychange",A);let P=()=>{p(true),v(d,g,{session_id:o,ended_at:new Date().toISOString()},n.onError);};typeof window<"u"&&window.addEventListener("beforeunload",P);let z={get sessionId(){return o},flush:()=>p(true),stop:j};return k=z,z}async function v(r,n,a,f){try{await fetch(`${r}/v1/replay/sessions`,{method:"POST",headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json"},body:JSON.stringify(a),keepalive:!0});}catch(d){f?.(d);}}async function X(r){if(typeof CompressionStream>"u"||typeof Blob>"u"||typeof Response>"u")return r;let a=new Blob([r]).stream().pipeThrough(new CompressionStream("gzip")),f=await new Response(a).arrayBuffer();return new Blob([f],{type:"application/gzip"})}async function Y(){try{let r=await import('rrweb');return r.record??r.default?.record??null}catch{return null}}exports.startReplay=Z;
|
package/dist/replay.d.cts
CHANGED
package/dist/replay.d.ts
CHANGED
package/dist/replay.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var H=new Set([1,3,6]);function W(r){return r.every(n=>{if(n.type!==3)return false;let a=n.data?.source;return a!==void 0&&H.has(a)})}var k=null;async function Z(r,n={}){if(typeof document>"u")return null;if(k)return k;let a=n.sampleRate??1;if(a<1&&Math.random()>a)return null;let f=n.rrwebRecord??await Y();if(!f)return null;let d=r.endpoint,g=r.apiKey,m=r,K=n.debug??m._debug??false,i=(e,s)=>{if(!K||typeof console>"u")return;let t=new Date().toISOString().slice(11,23);s?console.log(`%c[GL:replay ${t}]%c ${e}`,"color:#f59e0b;font-weight:bold","color:inherit",s):console.log(`%c[GL:replay ${t}]%c ${e}`,"color:#f59e0b;font-weight:bold","color:inherit");},O=n.flushIntervalMs??5e3,B=n.flushBytes??5e5,b=n.sessionTimeoutMs??1800*1e3,h=n.maxSessionMs??3600*1e3;i("config",{flushIntervalMs:O,flushBytes:B,sessionTimeoutMs:b/1e3+"s",maxSessionMs:h/1e3+"s"});let o=m.sessionId,u=[],y=0,_=`gl_replay_seq_${o}`,x=(()=>{try{return parseInt(sessionStorage?.getItem(_)??"0",10)||0}catch{return 0}})(),$=()=>{try{sessionStorage?.setItem(_,String(x));}catch{}},R=false,w=false,l=Date.now(),c=Date.now(),E=null,C=()=>{i("session:announce",{sessionId:o,distinctId:m.getDistinctId()}),v(d,g,{session_id:o,distinct_id:m.getDistinctId(),started_at:new Date(c).toISOString(),start_url:typeof location<"u"?location.href:null,last_url:typeof location<"u"?location.href:null},n.onError);},L=()=>{let e=o;i("session:seal",{sessionId:e,queueSize:u.length}),p(true),v(d,g,{session_id:e,ended_at:new Date().toISOString()},n.onError);},p=async(e=false)=>{if(u.length===0)return;if(!e&&W(u)){u=[],y=0;return}let s=u,t=s[0].timestamp,M=s[s.length-1].timestamp,G=s.length,T=o;u=[],y=0;let U=x++;$();try{let I=JSON.stringify(s),F=await X(I);i("chunk:upload",{sessionId:T,seq:U,events:G,bytes:I.length,range:`${new Date(t).toISOString()} \u2192 ${new Date(M).toISOString()}`});let Q=`${d}/v1/replay/chunks?session_id=${encodeURIComponent(T)}&seq=${U}&start_ts=${encodeURIComponent(new Date(t).toISOString())}&end_ts=${encodeURIComponent(new Date(M).toISOString())}&event_count=${G}`;await fetch(Q,{method:"POST",headers:{Authorization:`Bearer ${g}`,"Content-Type":"application/gzip","Content-Encoding":"gzip"},body:F,keepalive:!0});}catch(I){n.onError?.(I);}v(d,g,{session_id:T,last_url:typeof location<"u"?location.href:null,last_activity_at:new Date(M).toISOString(),has_error:R||void 0},n.onError);},S=()=>{let e=Date.now()-c,s=Date.now()-l;i("session:rotate",{oldSessionId:o,elapsed:Math.round(e/1e3)+"s",idle:Math.round(s/1e3)+"s"}),L();try{E?.();}catch(t){n.onError?.(t);}m.newSession(),o=m.getSessionId(),x=0,_=`gl_replay_seq_${o}`,$(),R=false,l=Date.now(),c=Date.now(),C(),q();},D=false,q=()=>{E=f({emit:e=>{if(w)return;e.type===3&&H.has(e.data?.source??-1)||(l=Date.now());let t=Date.now();if(!D&&(t-c>h||t-l>b)){D=true,i("emit:session-expired",{elapsed:Math.round((t-c)/1e3)+"s",idle:Math.round((t-l)/1e3)+"s"}),S(),D=false;return}u.push(e),y+=256,y>=B&&p();},checkoutEveryNms:6e4,maskAllInputs:n.maskAllInputs??true,blockSelector:n.blockSelector??"[data-gl-block]",maskTextSelector:n.maskTextSelector??"[data-gl-mask]",sampling:{mousemove:50,mouseInteraction:true,scroll:150,input:"last"}});},N=setInterval(()=>{globalThis.__gl_replay_has_error__&&(R=true);},1e3),j=()=>{if(!w){i("stop",{sessionId:o}),w=true,clearInterval(J),clearInterval(V),clearInterval(N),document?.removeEventListener("visibilitychange",A),typeof window<"u"&&window.removeEventListener("beforeunload",P);try{E?.();}catch(e){n.onError?.(e);}L(),k=null;}};i("start",{sessionId:o,sampleRate:a}),C(),q();let J=setInterval(()=>{p();},O),V=setInterval(()=>{if(w)return;let e=Date.now();if(e-l>b){i("watchdog:idle-timeout",{idle:Math.round((e-l)/1e3)+"s"}),S();return}if(e-c>h){i("watchdog:max-duration",{elapsed:Math.round((e-c)/1e3)+"s"}),S();return}},1e4),A=()=>{if(!w){if(document?.visibilityState==="hidden")i("visibility:hidden",{sessionId:o}),p(true),v(d,g,{session_id:o,ended_at:new Date().toISOString()},n.onError);else if(document?.visibilityState==="visible"){let e=Date.now(),s=e-l,t=e-c;i("visibility:visible",{idle:Math.round(s/1e3)+"s",elapsed:Math.round(t/1e3)+"s"}),s>b||t>h?S():l=e;}}};document.addEventListener("visibilitychange",A);let P=()=>{p(true),v(d,g,{session_id:o,ended_at:new Date().toISOString()},n.onError);};typeof window<"u"&&window.addEventListener("beforeunload",P);let z={get sessionId(){return o},flush:()=>p(true),stop:j};return k=z,z}async function v(r,n,a,f){try{await fetch(`${r}/v1/replay/sessions`,{method:"POST",headers:{Authorization:`Bearer ${n}`,"Content-Type":"application/json"},body:JSON.stringify(a),keepalive:!0});}catch(d){f?.(d);}}async function X(r){if(typeof CompressionStream>"u"||typeof Blob>"u"||typeof Response>"u")return r;let a=new Blob([r]).stream().pipeThrough(new CompressionStream("gzip")),f=await new Response(a).arrayBuffer();return new Blob([f],{type:"application/gzip"})}async function Y(){try{let r=await import('rrweb');return r.record??r.default?.record??null}catch{return null}}export{Z as startReplay};
|