@faststats/web 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/analytics-CMMFYUFq.js +1 -0
- package/dist/{error-i6Z4Acxj.js → error-DmR1BucX.js} +1 -1
- package/dist/module.d.ts +2 -3
- package/dist/module.js +1 -1
- package/dist/{replay-CLQirdnl.js → replay-B2VT_kl_.js} +1 -1
- package/package.json +1 -1
- package/src/feature-flags.ts +17 -14
- package/dist/analytics-Bi40uydz.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @faststats/web
|
|
2
2
|
|
|
3
|
+
## 0.2.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 3371933: fix: use identifier rather then server_id
|
|
8
|
+
|
|
9
|
+
## 0.2.2
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 9d7369d: fix: remove useless evaluation object from response
|
|
14
|
+
- 7b79f71: fix: use header over body for project token
|
|
15
|
+
- 7317c3c: fix: remove useless enabled propery
|
|
16
|
+
|
|
3
17
|
## 0.2.1
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as e,c as t,d as n,f as r,i,l as a,m as o,n as s,o as c,r as l,s as u,t as d,u as f}from"./types-Df70G0eM.js";async function p(e,t){if(t.projectToken&&t.projectId)throw Error(`provide either projectToken or projectId, not both`);if(t.identifier&&t.externalId)throw Error(`provide either serverId or externalId, not both`);let n=t.projectToken,r=t.projectId,i=t.identifier,o=t.externalId;if(!n&&!r)throw Error(`feature flag check requires projectToken or projectId`);if(!i&&!o)throw Error(`feature flag check requires serverId or externalId`);let s={key:e,...r?{projectId:r}:{},...i?{identifier:i}:{externalId:o}};t.attributes&&Object.keys(t.attributes).length>0&&(s.attributes=t.attributes);let c={"Content-Type":`application/json`};n&&(c.Authorization=`Bearer ${n}`);let l=a(t.baseUrl),u=await fetch(l,{method:`POST`,headers:c,body:JSON.stringify(s),credentials:`omit`,signal:t.signal});if(!u.ok){let e=``;try{let t=await u.json();typeof t.error==`string`&&t.error.length>0&&(e=` — ${t.error}`)}catch{}throw Error(`feature flag check failed: HTTP ${u.status}${e}`)}return await u.json()}let m=null,h;function g(){return m}function _(e,t){typeof window>`u`||w()||m?.track(e,t??{})}function v(e,t,n){typeof window>`u`||w()||m?.identify(e,t,n??{})}function y(e=!0){typeof window>`u`||w()||m?.logout(e)}function b(e){if(m){m.setConsentMode(e);return}h=e}function x(){b(`granted`)}function S(){b(`denied`)}function C(e){typeof window>`u`||w()||m?.reportError(e)}function w(){if(typeof localStorage>`u`)return!1;let e=localStorage.getItem(`disable-faststats`);return e===`true`||e===`1`}async function T(e){let{url:t,data:n,contentType:r=`application/json`,headers:i={},debug:a=!1,debugPrefix:o=`[Analytics]`,useBeacon:s=!0,keepalive:c=!0}=e;if(s&&typeof navigator<`u`&&typeof navigator.sendBeacon==`function`)try{let e=n instanceof Blob?n:typeof Blob<`u`?new Blob([n],{type:r}):n;if(navigator.sendBeacon(t,e))return a&&console.log(`${o} Sent via beacon`),!0}catch{}if(typeof fetch!=`function`)return a&&console.warn(`${o} Failed to send`),!1;try{let e=await fetch(t,{method:`POST`,body:n,headers:{"Content-Type":r,...i},keepalive:c}),s=e.ok;return a&&(s?console.log(`${o} Sent via fetch`):console.warn(`${o} Failed: ${e.status}`)),s}catch{return a&&console.warn(`${o} Failed to send`),!1}}function E(e){for(;e;){if(e instanceof HTMLAnchorElement&&e.href)return e;e=e.parentNode}return null}function D(){let e={};if(!location.search)return e;let t=new URLSearchParams(location.search);for(let n of[`utm_source`,`utm_medium`,`utm_campaign`,`utm_term`,`utm_content`]){let r=t.get(n);r&&(e[n]=r)}return e}var O=class{webEndpoint;baseUrl;featureFlagsBaseUrl;debug;started=!1;destroyed=!1;pageKey=``;navTimer=null;heartbeatTimer=null;scrollDepth=0;pageEntryTime=0;pagePath=``;pageUrl=``;pageHash=``;hasLeftCurrentPage=!1;scrollHandler=null;consentMode;cookielessWhilePending;cleanupCallbacks=[];childTrackers=[];pendingReportedErrors=[];errorTracker=null;handleVisibilityChange=()=>{document.visibilityState===`hidden`?(this.leavePage(),this.stopHeartbeat()):this.startHeartbeat()};handlePageHide=()=>{this.leavePage()};handlePopState=()=>{this.navigate()};handleHashChange=()=>{this.navigate()};constructor(e){this.options=e,this.baseUrl=n(e.baseUrl),this.featureFlagsBaseUrl=r(e.featureFlagsBaseUrl),this.webEndpoint=o(this.baseUrl),this.debug=e.debug??!1,this.consentMode=e.consent?.mode??`granted`,this.cookielessWhilePending=e.consent?.cookielessWhilePending??!0,h!==void 0&&(this.consentMode=h,h=void 0),(e.autoTrack??!0)&&this.init()}log(e){this.debug&&console.log(`[Analytics] ${e}`)}init(){if(!(typeof window>`u`)){if(w()){this.log(`disabled`);return}m=this,t(this.isCookielessMode()),setTimeout(()=>void this.start(),0)}}registerCleanup(e){this.cleanupCallbacks.push(e)}addWindowListener(e,t){window.addEventListener(e,t),this.registerCleanup(()=>window.removeEventListener(e,t))}addDocumentListener(e,t){document.addEventListener(e,t),this.registerCleanup(()=>document.removeEventListener(e,t))}patchHistory(){let e=history.pushState.bind(history),t=history.replaceState.bind(history);history.pushState=(t,n,r)=>{e(t,n,r),this.navigate()},history.replaceState=(e,n,r)=>{t(e,n,r),this.navigate()},this.registerCleanup(()=>{history.pushState=e,history.replaceState=t})}ensureStarted(){return typeof window>`u`||this.destroyed||w()?!1:(this.started||this.start(),!0)}stopHeartbeat(){this.heartbeatTimer&&=(clearInterval(this.heartbeatTimer),null)}stopNavigationTimer(){this.navTimer&&=(clearTimeout(this.navTimer),null)}stopChildTrackers(){for(let e of this.childTrackers.splice(0))e.stop?.();this.errorTracker=null}async start(){if(this.started||this.destroyed||typeof window>`u`)return;if(m&&m!==this){this.log(`already started by another instance`);return}if(w()){this.log(`disabled`);return}this.started=!0,m=this,t(this.isCookielessMode());let e=this.options;if(e.trackErrors)try{let{default:t}=await import(`./error-DmR1BucX.js`),n=new t({siteKey:e.siteKey,baseUrl:this.baseUrl,debug:this.debug});for(n.start(),this.errorTracker=n,this.childTrackers.push(n);this.pendingReportedErrors.length>0;){let e=this.pendingReportedErrors.shift();e&&n.captureError(e)}this.log(`error loaded`)}catch(e){this.log(`failed to initialize error tracker: ${String(e)}`)}if(e.trackWebVitals)try{let{default:t}=await import(`./web-vitals-gcUR-TX_.js`),n=new t({siteKey:e.siteKey,baseUrl:this.baseUrl,debug:this.debug,samplingPercentage:d(e.webVitals?.sampling?.percentage)});n.start(),this.childTrackers.push(n),this.log(`web-vitals loaded`)}catch(e){this.log(`failed to initialize web-vitals tracker: ${String(e)}`)}if(e.trackReplay)try{let{default:t}=await import(`./replay-B2VT_kl_.js`),n=new t({siteKey:e.siteKey,baseUrl:this.baseUrl,debug:this.debug,...e.replayOptions});n.start(),this.childTrackers.push(n),this.log(`replay loaded`)}catch(e){this.log(`failed to initialize replay tracker: ${String(e)}`)}this.enterPage(),this.pageview({trigger:`load`}),this.links(),this.trackScroll(),this.startHeartbeat(),this.addDocumentListener(`visibilitychange`,this.handleVisibilityChange),this.addWindowListener(`pagehide`,this.handlePageHide),this.addWindowListener(`popstate`,this.handlePopState),e.trackHash&&this.addWindowListener(`hashchange`,this.handleHashChange),this.patchHistory()}destroy(){if(!this.destroyed){for(this.started&&typeof window<`u`&&this.leavePage(),this.pendingReportedErrors.length=0,this.stopNavigationTimer(),this.stopHeartbeat(),this.scrollHandler&&typeof window<`u`&&(window.removeEventListener(`scroll`,this.scrollHandler),this.scrollHandler=null);this.cleanupCallbacks.length>0;)this.cleanupCallbacks.pop()?.();this.stopChildTrackers(),m===this&&(m=null),this.started=!1,this.destroyed=!0}}pageview(e={}){if(!this.ensureStarted())return;let t=`${location.pathname}|${this.options.trackHash??!1?location.hash:``}`;t!==this.pageKey&&(this.pageKey=t,this.send(`pageview`,e))}track(e,t={}){this.ensureStarted()&&this.send(e,t)}identify(e,t,n={}){if(!this.ensureStarted()||this.isCookielessMode())return;let r=e.trim(),i=t.trim();!r||!i||T({url:f(this.baseUrl),data:JSON.stringify({token:this.options.siteKey,identifier:s(!1),externalId:r,email:i,name:n.name?.trim()||void 0,phone:n.phone?.trim()||void 0,avatarUrl:n.avatarUrl?.trim()||void 0,traits:n.traits??{}}),contentType:`text/plain`,debug:this.debug,debugPrefix:`[Analytics] identify`})}logout(e=!0){this.ensureStarted()&&(e&&c(this.isCookielessMode()),u())}setConsentMode(e){this.consentMode=e,t(this.isCookielessMode())}optIn(){this.setConsentMode(`granted`)}optOut(){this.setConsentMode(`denied`)}getConsentMode(){return this.consentMode}getAnonymousId(){return s(this.isCookielessMode())}getSessionId(){return l()}async checkFeatureFlag(e,t,n){if(typeof window>`u`||w())return{enabled:!1};let r=n?.externalId?.trim();if(r)return p(e,{baseUrl:this.featureFlagsBaseUrl,projectToken:this.options.siteKey,externalId:r,attributes:t,signal:n?.signal});let i=this.getAnonymousId();return i?p(e,{baseUrl:this.featureFlagsBaseUrl,projectToken:this.options.siteKey,serverId:i,attributes:t,signal:n?.signal}):{enabled:!1}}reportError(e){if(this.destroyed||typeof window>`u`||w()||!(this.options.trackErrors??!1)||!this.ensureStarted())return;let t=this.errorTracker;if(t){t.captureError(e);return}this.pendingReportedErrors.length>=50&&this.pendingReportedErrors.shift(),this.pendingReportedErrors.push(e)}isCookielessMode(){return this.options.cookieless||this.consentMode===`denied`?!0:this.consentMode===`pending`?this.cookielessWhilePending:!1}send(e,t={}){if(typeof window>`u`||this.destroyed||w())return;let n=s(this.isCookielessMode()),r=JSON.stringify({token:this.options.siteKey,...n?{userId:n}:{},sessionId:l(),data:{event:e,page:location.pathname,referrer:document.referrer||null,title:document.title||``,url:location.href,...D(),...t}});this.log(e),T({url:this.webEndpoint,data:r,contentType:`text/plain`,debug:this.debug,debugPrefix:`[Analytics] ${e}`})}enterPage(){this.pageEntryTime=Date.now(),this.pagePath=location.pathname,this.pageUrl=location.href,this.pageHash=location.hash,this.scrollDepth=0,this.hasLeftCurrentPage=!1}leavePage(){if(this.destroyed||this.hasLeftCurrentPage)return;this.hasLeftCurrentPage=!0;let e=Date.now();this.send(`page_leave`,{page:this.pagePath,url:this.pageUrl,time_on_page:e-this.pageEntryTime,scroll_depth:this.scrollDepth,session_duration:e-i()})}trackScroll(){this.scrollHandler&&window.removeEventListener(`scroll`,this.scrollHandler);let e=()=>{let e=document.documentElement,t=document.body,n=window.innerHeight,r=Math.max(e.scrollHeight,t.scrollHeight);if(r<=n){this.scrollDepth=100;return}let i=Math.min(100,Math.round(((window.scrollY||e.scrollTop)+n)/r*100));i>this.scrollDepth&&(this.scrollDepth=i)};this.scrollHandler=e,e(),window.addEventListener(`scroll`,e,{passive:!0})}startHeartbeat(){this.stopHeartbeat(),this.heartbeatTimer=setInterval(()=>{if(document.visibilityState===`hidden`){this.stopHeartbeat();return}e()},300*1e3)}navigate(){!this.started||this.destroyed||(this.stopNavigationTimer(),this.navTimer=setTimeout(()=>{this.navTimer=null;let e=location.pathname!==this.pagePath,t=(this.options.trackHash??!1)&&location.hash!==this.pageHash;!e&&!t||(this.leavePage(),this.enterPage(),this.trackScroll(),this.pageview({trigger:`navigation`}))},300))}links(){let e=e=>{let t=E(e.target);t&&t.host!==location.host&&this.track(`outbound_link`,{outbound_link:t.href})};this.addDocumentListener(`click`,e),this.addDocumentListener(`auxclick`,e)}};export{y as a,C as c,_ as d,p as f,w as i,T as l,g as n,x as o,v as r,S as s,O as t,b as u};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{m as e,n as t,r as n}from"./types-Df70G0eM.js";import{l as r}from"./analytics-
|
|
1
|
+
import{m as e,n as t,r as n}from"./types-Df70G0eM.js";import{l as r}from"./analytics-CMMFYUFq.js";const i=/(?:^|\()(chrome|moz|ms-browser|safari-web)-extension:\/\//,a=e=>e?.split(`
|
|
2
2
|
`).map(e=>e.trim()).filter(Boolean);function o(e){if(e instanceof Error)return{error:e.name?.trim()||`Error`,message:e.message,stack:a(e.stack),cause:o(e.cause)};if(typeof e==`string`)return{error:`Error`,message:e}}function s(e){return e?`${e.error}\0${e.message??``}\0${s(e.cause)}`:``}function c(e){let t=[e.kind,e.handled?`handled`:`unhandled`,e.message,e.filename??``,e.lineno??``,s(e.cause)].join(`\0`),n=2166136261,r=3598710387;for(let e=0;e<t.length;e++){let i=t.charCodeAt(e);n=Math.imul(n^i,16777619),r=Math.imul(r^i,2246822519)}return`err_${(n>>>0).toString(16).padStart(8,`0`)}${(r>>>0).toString(16).padStart(8,`0`)}`}var l=class{endpoint;handled=new WeakSet;queue=new Map;timer=null;started=!1;constructor(t){this.options=t,this.endpoint=e(t.baseUrl)}get debug(){return this.options.debug??!1}get flushInterval(){return this.options.flushInterval??5e3}get maxQueueSize(){return this.options.maxQueueSize??50}log(...e){this.debug&&console.log(`[ErrorTracker]`,...e)}start(){this.started||typeof window>`u`||(this.started=!0,window.addEventListener(`error`,this.onError),window.addEventListener(`unhandledrejection`,this.onRejection),document.addEventListener(`visibilitychange`,this.onVisibilityChange),window.addEventListener(`pagehide`,this.flush),this.timer=setInterval(this.flush,this.flushInterval),this.log(`Started listening for errors`))}stop(){!this.started||typeof window>`u`||(this.started=!1,window.removeEventListener(`error`,this.onError),window.removeEventListener(`unhandledrejection`,this.onRejection),document.removeEventListener(`visibilitychange`,this.onVisibilityChange),window.removeEventListener(`pagehide`,this.flush),this.timer&&clearInterval(this.timer),this.timer=null,this.flush(),this.log(`Stopped listening for errors`))}captureError(e){this.record({kind:`error`,message:e.message,stack:e.stack,handled:!0,cause:o(e.cause)},e)}onError=e=>{let t=e.error;this.record({kind:`error`,message:e.message||`Unknown error`,filename:e.filename||void 0,lineno:e.lineno||void 0,stack:t instanceof Error?t.stack:void 0,handled:!1,cause:t instanceof Error?o(t.cause):void 0},t)};onRejection=e=>{let t=e.reason;this.record({kind:`unhandledrejection`,message:t.message||`Unhandled promise rejection`,stack:t.stack||void 0,handled:!1,cause:o(t.cause)},t)};onVisibilityChange=()=>{document.visibilityState===`hidden`&&this.flush()};record(e,t){if(t instanceof Error){if(this.handled.has(t)){this.log(`Skipping duplicate:`,t.message);return}this.handled.add(t)}if(i.test(`${e.filename??``}\n${e.stack??``}`))return;let n=c(e),r=this.queue.get(n);r?r.count+=1:this.queue.set(n,{hash:n,count:1,error:e.kind===`unhandledrejection`?`UnhandledRejection`:`Error`,message:e.message,stack:a(e.stack),handled:e.handled,...e.cause?{cause:e.cause}:{}}),this.log(`Captured error:`,e),this.queue.size>=this.maxQueueSize&&this.flush()}flush=()=>{if(this.queue.size===0)return;let e=[...this.queue.values()];this.queue.clear();let i=t(),a=globalThis.__SOURCEMAPS_BUILD__,o=typeof a?.buildId==`string`&&a.buildId.trim()?a.buildId:void 0,s=JSON.stringify({token:this.options.siteKey,...i?{userId:i}:{},sessionId:n(),...o?{buildId:o}:{},data:{url:location.href,page:location.pathname,referrer:document.referrer||null,title:document.title},errors:e});this.log(`Flushing errors:`,e),this.log(`Payload:`,s),r({url:this.endpoint,data:s,debug:this.debug,debugPrefix:`[ErrorTracker]`})}};export{l as default};
|
package/dist/module.d.ts
CHANGED
|
@@ -3,8 +3,7 @@ import { SlimDOMOptions } from "rrweb-snapshot";
|
|
|
3
3
|
|
|
4
4
|
//#region src/feature-flags.d.ts
|
|
5
5
|
type FeatureFlagEvaluation = {
|
|
6
|
-
|
|
7
|
-
value?: string;
|
|
6
|
+
value: string;
|
|
8
7
|
variantKey?: string;
|
|
9
8
|
variantValue?: string;
|
|
10
9
|
};
|
|
@@ -12,7 +11,7 @@ type FeatureFlagCheckContext = {
|
|
|
12
11
|
baseUrl?: string;
|
|
13
12
|
projectToken?: string;
|
|
14
13
|
projectId?: string;
|
|
15
|
-
|
|
14
|
+
identifier?: string;
|
|
16
15
|
externalId?: string;
|
|
17
16
|
attributes?: Record<string, unknown>;
|
|
18
17
|
signal?: AbortSignal;
|
package/dist/module.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{f as e,l as t}from"./types-Df70G0eM.js";import{a as n,c as r,d as i,f as a,i as o,l as s,n as c,o as l,r as u,s as d,t as f,u as p}from"./analytics-
|
|
1
|
+
import{f as e,l as t}from"./types-Df70G0eM.js";import{a as n,c as r,d as i,f as a,i as o,l as s,n as c,o as l,r as u,s as d,t as f,u as p}from"./analytics-CMMFYUFq.js";export{f as WebAnalytics,t as featureFlagsCheckUrl,a as fetchFeatureFlagEvaluation,c as getInstance,u as identify,o as isTrackingDisabled,n as logout,e as normalizeFeatureFlagsBaseUrl,l as optIn,d as optOut,r as reportError,s as sendData,p as setConsentMode,i as trackEvent};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e,p as t,r as n,t as r}from"./types-Df70G0eM.js";import{l as i}from"./analytics-
|
|
1
|
+
import{n as e,p as t,r as n,t as r}from"./types-Df70G0eM.js";import{l as i}from"./analytics-CMMFYUFq.js";import{getRecordConsolePlugin as a}from"@rrweb/rrweb-plugin-console-record";import{getRecordSequentialIdPlugin as o}from"@rrweb/rrweb-plugin-sequential-id-record";import{EventType as s,record as c}from"rrweb";const l={mousemove:50,mouseInteraction:!0,scroll:150,media:800,input:`last`},u={script:!0,comment:!0,headFavicon:!0,headWhitespace:!0,headMetaDescKeywords:!0,headMetaSocial:!0,headMetaRobots:!0,headMetaHttpEquiv:!0,headMetaAuthorship:!0};var d=class{endpoint;compressionSupported=typeof window<`u`&&`CompressionStream`in window;sampled;events=[];pending=[];started=!1;startTime=0;sequence=0;intervalId=null;flushTask=null;retryTask=null;stopRecording;sending=!1;constructor(e){this.options=e,this.endpoint=t(e.baseUrl),this.sampled=Math.random()*100<r(e.samplingPercentage)}get debug(){return this.options.debug??!1}get flushInterval(){return this.options.flushInterval??1e4}get maxEvents(){return this.options.maxEvents??500}get maxPendingBatches(){return this.options.maxPendingBatches??30}get minReplayLengthMs(){return this.options.minReplayLengthMs??3e3}log(...e){this.debug&&console.log(`[Replay]`,...e)}start(){this.started||typeof window>`u`||!this.sampled||(this.started=!0,this.startTime=Date.now(),this.stopRecording=c({emit:this.onEvent,sampling:this.options.sampling??l,slimDOMOptions:this.options.slimDOMOptions??u,maskAllInputs:this.options.maskAllInputs??!0,maskInputOptions:this.options.maskInputOptions??{password:!0,email:!0,tel:!0},blockClass:this.options.blockClass,blockSelector:this.options.blockSelector,maskTextClass:this.options.maskTextClass,maskTextSelector:this.options.maskTextSelector,checkoutEveryNms:this.options.checkoutEveryNms??6e4,checkoutEveryNth:this.options.checkoutEveryNth,plugins:[o({key:`_faststatsSeqId`}),...this.options.recordConsole??!0?[a()]:[]]}),this.intervalId=setInterval(this.requestFlush,this.flushInterval),window.addEventListener(`beforeunload`,this.onUnload),window.addEventListener(`pagehide`,this.onUnload),document.addEventListener(`visibilitychange`,this.onVisibilityChange),this.log(`Recording started`))}stop(){if(this.started){if(this.started=!1,this.stopRecording?.(),this.stopRecording=void 0,this.intervalId&&clearInterval(this.intervalId),this.flushTask&&clearTimeout(this.flushTask),this.retryTask&&clearTimeout(this.retryTask),this.intervalId=null,this.flushTask=null,this.retryTask=null,window.removeEventListener(`beforeunload`,this.onUnload),window.removeEventListener(`pagehide`,this.onUnload),document.removeEventListener(`visibilitychange`,this.onVisibilityChange),!this.hasReachedMinLength()){this.events.length=0,this.log(`Session too short (${Date.now()-this.startTime}ms), discarding events`);return}this.flush(!0),this.log(`Recording stopped`)}}getSessionId(){return n()}onEvent=(e,t)=>{this.events.push(e),(t||this.events.length>=this.maxEvents||e.type===s.FullSnapshot&&this.hasReachedMinLength())&&this.requestFlush()};onUnload=()=>{this.flush(!0)};onVisibilityChange=()=>{document.visibilityState===`hidden`&&this.flush(!0)};hasReachedMinLength(){return this.minReplayLengthMs<=0||Date.now()-this.startTime>=this.minReplayLengthMs}requestFlush=()=>{this.flushTask||this.sending||this.events.length===0||(this.flushTask=setTimeout(()=>{this.flushTask=null,this.flush(!1)},0))};createBatch(t){let r=e();return{token:this.options.siteKey,sessionId:n(),...r?{identifier:r}:{},sequence:this.sequence++,timestamp:Date.now(),url:window.location.href,events:t}}async encodeBatch(e,t){let n=JSON.stringify(e);if(!this.compressionSupported||t)return{data:new Blob([n],{type:`application/json`}),isCompressed:!1};try{return{data:await this.compress(n),isCompressed:!0}}catch{return this.log(`Compression failed, using uncompressed`),{data:new Blob([n],{type:`application/json`}),isCompressed:!1}}}async flush(e){if(!this.sending&&(this.events.length>0&&(this.hasReachedMinLength()?this.pending.push(this.createBatch(this.events.splice(0))):this.log(`Too short (${Date.now()-this.startTime}ms), skipping flush`)),this.pending.length!==0)){this.sending=!0;try{for(;this.pending.length>0;){let t=this.pending[0];if(!t)break;let n=await this.encodeBatch(t,e);if(!await this.send(n.data,n.isCompressed,e)){this.pending.length>=this.maxPendingBatches&&(this.log(`Pending buffer full, dropping batch ${t.sequence}`),this.pending.shift()),this.scheduleRetry();break}this.log(`Sent ${t.events.length} events (seq: ${t.sequence})`),this.pending.shift(),e=!1}}finally{this.sending=!1}}}scheduleRetry(){this.retryTask||=setTimeout(()=>{this.retryTask=null,this.flush(!1)},1e3)}async compress(e){let t=new TextEncoder().encode(e),n=new CompressionStream(`gzip`),r=n.writable.getWriter();await r.write(t),await r.close();let i=[],a=n.readable.getReader();for(;;){let{done:e,value:t}=await a.read();if(e)break;t&&i.push(t)}let o=i.reduce((e,t)=>e+t.length,0),s=new Uint8Array(o),c=0;for(let e of i)s.set(e,c),c+=e.length;return this.log(`Compressed: ${t.length} → ${s.length} bytes (${(s.length/t.length*100).toFixed(1)}%)`),new Blob([s],{type:`application/octet-stream`})}send(e,t,n){return i({url:t?`${this.endpoint}?encoding=gzip`:this.endpoint,data:e,contentType:t?`application/octet-stream`:`application/json`,debug:this.debug,debugPrefix:`[Replay] ${(e.size/1024).toFixed(1)}KB`,useBeacon:n,keepalive:n})??Promise.resolve(!1)}};export{d as default};
|
package/package.json
CHANGED
package/src/feature-flags.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { featureFlagsCheckUrl } from "./utils/api-urls";
|
|
2
2
|
|
|
3
3
|
export type FeatureFlagEvaluation = {
|
|
4
|
-
|
|
5
|
-
value?: string;
|
|
4
|
+
value: string;
|
|
6
5
|
variantKey?: string;
|
|
7
6
|
variantValue?: string;
|
|
8
7
|
};
|
|
@@ -11,7 +10,7 @@ export type FeatureFlagCheckContext = {
|
|
|
11
10
|
baseUrl?: string;
|
|
12
11
|
projectToken?: string;
|
|
13
12
|
projectId?: string;
|
|
14
|
-
|
|
13
|
+
identifier?: string;
|
|
15
14
|
externalId?: string;
|
|
16
15
|
attributes?: Record<string, unknown>;
|
|
17
16
|
signal?: AbortSignal;
|
|
@@ -24,36 +23,43 @@ export async function fetchFeatureFlagEvaluation(
|
|
|
24
23
|
if (context.projectToken && context.projectId) {
|
|
25
24
|
throw new Error("provide either projectToken or projectId, not both");
|
|
26
25
|
}
|
|
27
|
-
if (context.
|
|
26
|
+
if (context.identifier && context.externalId) {
|
|
28
27
|
throw new Error("provide either serverId or externalId, not both");
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
const projectToken = context.projectToken;
|
|
32
31
|
const projectId = context.projectId;
|
|
33
|
-
const
|
|
32
|
+
const identifier = context.identifier;
|
|
34
33
|
const externalId = context.externalId;
|
|
35
34
|
|
|
36
35
|
if (!projectToken && !projectId) {
|
|
37
36
|
throw new Error("feature flag check requires projectToken or projectId");
|
|
38
37
|
}
|
|
39
|
-
if (!
|
|
38
|
+
if (!identifier && !externalId) {
|
|
40
39
|
throw new Error("feature flag check requires serverId or externalId");
|
|
41
40
|
}
|
|
42
41
|
|
|
43
42
|
const body: Record<string, unknown> = {
|
|
44
43
|
key: flagKey,
|
|
45
|
-
...(
|
|
46
|
-
...(
|
|
44
|
+
...(projectId ? { projectId } : {}),
|
|
45
|
+
...(identifier ? { identifier } : { externalId }),
|
|
47
46
|
};
|
|
48
47
|
|
|
49
48
|
if (context.attributes && Object.keys(context.attributes).length > 0) {
|
|
50
49
|
body.attributes = context.attributes;
|
|
51
50
|
}
|
|
52
51
|
|
|
52
|
+
const headers: Record<string, string> = {
|
|
53
|
+
"Content-Type": "application/json",
|
|
54
|
+
};
|
|
55
|
+
if (projectToken) {
|
|
56
|
+
headers.Authorization = `Bearer ${projectToken}`;
|
|
57
|
+
}
|
|
58
|
+
|
|
53
59
|
const url = featureFlagsCheckUrl(context.baseUrl);
|
|
54
60
|
const res = await fetch(url, {
|
|
55
61
|
method: "POST",
|
|
56
|
-
headers
|
|
62
|
+
headers,
|
|
57
63
|
body: JSON.stringify(body),
|
|
58
64
|
credentials: "omit",
|
|
59
65
|
signal: context.signal,
|
|
@@ -72,9 +78,6 @@ export async function fetchFeatureFlagEvaluation(
|
|
|
72
78
|
throw new Error(`feature flag check failed: HTTP ${res.status}${detail}`);
|
|
73
79
|
}
|
|
74
80
|
|
|
75
|
-
const data = (await res.json()) as
|
|
76
|
-
|
|
77
|
-
return evaluation?.enabled === true || evaluation?.enabled === false
|
|
78
|
-
? evaluation
|
|
79
|
-
: { enabled: false };
|
|
81
|
+
const data = (await res.json()) as FeatureFlagEvaluation;
|
|
82
|
+
return data;
|
|
80
83
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a as e,c as t,d as n,f as r,i,l as a,m as o,n as s,o as c,r as l,s as u,t as d,u as f}from"./types-Df70G0eM.js";async function p(e,t){if(t.projectToken&&t.projectId)throw Error(`provide either projectToken or projectId, not both`);if(t.serverId&&t.externalId)throw Error(`provide either serverId or externalId, not both`);let n=t.projectToken,r=t.projectId,i=t.serverId,o=t.externalId;if(!n&&!r)throw Error(`feature flag check requires projectToken or projectId`);if(!i&&!o)throw Error(`feature flag check requires serverId or externalId`);let s={key:e,...n?{projectToken:n}:{projectId:r},...i?{serverId:i}:{externalId:o}};t.attributes&&Object.keys(t.attributes).length>0&&(s.attributes=t.attributes);let c=a(t.baseUrl),l=await fetch(c,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(s),credentials:`omit`,signal:t.signal});if(!l.ok){let e=``;try{let t=await l.json();typeof t.error==`string`&&t.error.length>0&&(e=` — ${t.error}`)}catch{}throw Error(`feature flag check failed: HTTP ${l.status}${e}`)}let u=(await l.json()).evaluation;return u?.enabled===!0||u?.enabled===!1?u:{enabled:!1}}let m=null,h;function g(){return m}function _(e,t){typeof window>`u`||w()||m?.track(e,t??{})}function v(e,t,n){typeof window>`u`||w()||m?.identify(e,t,n??{})}function y(e=!0){typeof window>`u`||w()||m?.logout(e)}function b(e){if(m){m.setConsentMode(e);return}h=e}function x(){b(`granted`)}function S(){b(`denied`)}function C(e){typeof window>`u`||w()||m?.reportError(e)}function w(){if(typeof localStorage>`u`)return!1;let e=localStorage.getItem(`disable-faststats`);return e===`true`||e===`1`}async function T(e){let{url:t,data:n,contentType:r=`application/json`,headers:i={},debug:a=!1,debugPrefix:o=`[Analytics]`,useBeacon:s=!0,keepalive:c=!0}=e;if(s&&typeof navigator<`u`&&typeof navigator.sendBeacon==`function`)try{let e=n instanceof Blob?n:typeof Blob<`u`?new Blob([n],{type:r}):n;if(navigator.sendBeacon(t,e))return a&&console.log(`${o} Sent via beacon`),!0}catch{}if(typeof fetch!=`function`)return a&&console.warn(`${o} Failed to send`),!1;try{let e=await fetch(t,{method:`POST`,body:n,headers:{"Content-Type":r,...i},keepalive:c}),s=e.ok;return a&&(s?console.log(`${o} Sent via fetch`):console.warn(`${o} Failed: ${e.status}`)),s}catch{return a&&console.warn(`${o} Failed to send`),!1}}function E(e){for(;e;){if(e instanceof HTMLAnchorElement&&e.href)return e;e=e.parentNode}return null}function D(){let e={};if(!location.search)return e;let t=new URLSearchParams(location.search);for(let n of[`utm_source`,`utm_medium`,`utm_campaign`,`utm_term`,`utm_content`]){let r=t.get(n);r&&(e[n]=r)}return e}var O=class{webEndpoint;baseUrl;featureFlagsBaseUrl;debug;started=!1;destroyed=!1;pageKey=``;navTimer=null;heartbeatTimer=null;scrollDepth=0;pageEntryTime=0;pagePath=``;pageUrl=``;pageHash=``;hasLeftCurrentPage=!1;scrollHandler=null;consentMode;cookielessWhilePending;cleanupCallbacks=[];childTrackers=[];pendingReportedErrors=[];errorTracker=null;handleVisibilityChange=()=>{document.visibilityState===`hidden`?(this.leavePage(),this.stopHeartbeat()):this.startHeartbeat()};handlePageHide=()=>{this.leavePage()};handlePopState=()=>{this.navigate()};handleHashChange=()=>{this.navigate()};constructor(e){this.options=e,this.baseUrl=n(e.baseUrl),this.featureFlagsBaseUrl=r(e.featureFlagsBaseUrl),this.webEndpoint=o(this.baseUrl),this.debug=e.debug??!1,this.consentMode=e.consent?.mode??`granted`,this.cookielessWhilePending=e.consent?.cookielessWhilePending??!0,h!==void 0&&(this.consentMode=h,h=void 0),(e.autoTrack??!0)&&this.init()}log(e){this.debug&&console.log(`[Analytics] ${e}`)}init(){if(!(typeof window>`u`)){if(w()){this.log(`disabled`);return}m=this,t(this.isCookielessMode()),setTimeout(()=>void this.start(),0)}}registerCleanup(e){this.cleanupCallbacks.push(e)}addWindowListener(e,t){window.addEventListener(e,t),this.registerCleanup(()=>window.removeEventListener(e,t))}addDocumentListener(e,t){document.addEventListener(e,t),this.registerCleanup(()=>document.removeEventListener(e,t))}patchHistory(){let e=history.pushState.bind(history),t=history.replaceState.bind(history);history.pushState=(t,n,r)=>{e(t,n,r),this.navigate()},history.replaceState=(e,n,r)=>{t(e,n,r),this.navigate()},this.registerCleanup(()=>{history.pushState=e,history.replaceState=t})}ensureStarted(){return typeof window>`u`||this.destroyed||w()?!1:(this.started||this.start(),!0)}stopHeartbeat(){this.heartbeatTimer&&=(clearInterval(this.heartbeatTimer),null)}stopNavigationTimer(){this.navTimer&&=(clearTimeout(this.navTimer),null)}stopChildTrackers(){for(let e of this.childTrackers.splice(0))e.stop?.();this.errorTracker=null}async start(){if(this.started||this.destroyed||typeof window>`u`)return;if(m&&m!==this){this.log(`already started by another instance`);return}if(w()){this.log(`disabled`);return}this.started=!0,m=this,t(this.isCookielessMode());let e=this.options;if(e.trackErrors)try{let{default:t}=await import(`./error-i6Z4Acxj.js`),n=new t({siteKey:e.siteKey,baseUrl:this.baseUrl,debug:this.debug});for(n.start(),this.errorTracker=n,this.childTrackers.push(n);this.pendingReportedErrors.length>0;){let e=this.pendingReportedErrors.shift();e&&n.captureError(e)}this.log(`error loaded`)}catch(e){this.log(`failed to initialize error tracker: ${String(e)}`)}if(e.trackWebVitals)try{let{default:t}=await import(`./web-vitals-gcUR-TX_.js`),n=new t({siteKey:e.siteKey,baseUrl:this.baseUrl,debug:this.debug,samplingPercentage:d(e.webVitals?.sampling?.percentage)});n.start(),this.childTrackers.push(n),this.log(`web-vitals loaded`)}catch(e){this.log(`failed to initialize web-vitals tracker: ${String(e)}`)}if(e.trackReplay)try{let{default:t}=await import(`./replay-CLQirdnl.js`),n=new t({siteKey:e.siteKey,baseUrl:this.baseUrl,debug:this.debug,...e.replayOptions});n.start(),this.childTrackers.push(n),this.log(`replay loaded`)}catch(e){this.log(`failed to initialize replay tracker: ${String(e)}`)}this.enterPage(),this.pageview({trigger:`load`}),this.links(),this.trackScroll(),this.startHeartbeat(),this.addDocumentListener(`visibilitychange`,this.handleVisibilityChange),this.addWindowListener(`pagehide`,this.handlePageHide),this.addWindowListener(`popstate`,this.handlePopState),e.trackHash&&this.addWindowListener(`hashchange`,this.handleHashChange),this.patchHistory()}destroy(){if(!this.destroyed){for(this.started&&typeof window<`u`&&this.leavePage(),this.pendingReportedErrors.length=0,this.stopNavigationTimer(),this.stopHeartbeat(),this.scrollHandler&&typeof window<`u`&&(window.removeEventListener(`scroll`,this.scrollHandler),this.scrollHandler=null);this.cleanupCallbacks.length>0;)this.cleanupCallbacks.pop()?.();this.stopChildTrackers(),m===this&&(m=null),this.started=!1,this.destroyed=!0}}pageview(e={}){if(!this.ensureStarted())return;let t=`${location.pathname}|${this.options.trackHash??!1?location.hash:``}`;t!==this.pageKey&&(this.pageKey=t,this.send(`pageview`,e))}track(e,t={}){this.ensureStarted()&&this.send(e,t)}identify(e,t,n={}){if(!this.ensureStarted()||this.isCookielessMode())return;let r=e.trim(),i=t.trim();!r||!i||T({url:f(this.baseUrl),data:JSON.stringify({token:this.options.siteKey,identifier:s(!1),externalId:r,email:i,name:n.name?.trim()||void 0,phone:n.phone?.trim()||void 0,avatarUrl:n.avatarUrl?.trim()||void 0,traits:n.traits??{}}),contentType:`text/plain`,debug:this.debug,debugPrefix:`[Analytics] identify`})}logout(e=!0){this.ensureStarted()&&(e&&c(this.isCookielessMode()),u())}setConsentMode(e){this.consentMode=e,t(this.isCookielessMode())}optIn(){this.setConsentMode(`granted`)}optOut(){this.setConsentMode(`denied`)}getConsentMode(){return this.consentMode}getAnonymousId(){return s(this.isCookielessMode())}getSessionId(){return l()}async checkFeatureFlag(e,t,n){if(typeof window>`u`||w())return{enabled:!1};let r=n?.externalId?.trim();if(r)return p(e,{baseUrl:this.featureFlagsBaseUrl,projectToken:this.options.siteKey,externalId:r,attributes:t,signal:n?.signal});let i=this.getAnonymousId();return i?p(e,{baseUrl:this.featureFlagsBaseUrl,projectToken:this.options.siteKey,serverId:i,attributes:t,signal:n?.signal}):{enabled:!1}}reportError(e){if(this.destroyed||typeof window>`u`||w()||!(this.options.trackErrors??!1)||!this.ensureStarted())return;let t=this.errorTracker;if(t){t.captureError(e);return}this.pendingReportedErrors.length>=50&&this.pendingReportedErrors.shift(),this.pendingReportedErrors.push(e)}isCookielessMode(){return this.options.cookieless||this.consentMode===`denied`?!0:this.consentMode===`pending`?this.cookielessWhilePending:!1}send(e,t={}){if(typeof window>`u`||this.destroyed||w())return;let n=s(this.isCookielessMode()),r=JSON.stringify({token:this.options.siteKey,...n?{userId:n}:{},sessionId:l(),data:{event:e,page:location.pathname,referrer:document.referrer||null,title:document.title||``,url:location.href,...D(),...t}});this.log(e),T({url:this.webEndpoint,data:r,contentType:`text/plain`,debug:this.debug,debugPrefix:`[Analytics] ${e}`})}enterPage(){this.pageEntryTime=Date.now(),this.pagePath=location.pathname,this.pageUrl=location.href,this.pageHash=location.hash,this.scrollDepth=0,this.hasLeftCurrentPage=!1}leavePage(){if(this.destroyed||this.hasLeftCurrentPage)return;this.hasLeftCurrentPage=!0;let e=Date.now();this.send(`page_leave`,{page:this.pagePath,url:this.pageUrl,time_on_page:e-this.pageEntryTime,scroll_depth:this.scrollDepth,session_duration:e-i()})}trackScroll(){this.scrollHandler&&window.removeEventListener(`scroll`,this.scrollHandler);let e=()=>{let e=document.documentElement,t=document.body,n=window.innerHeight,r=Math.max(e.scrollHeight,t.scrollHeight);if(r<=n){this.scrollDepth=100;return}let i=Math.min(100,Math.round(((window.scrollY||e.scrollTop)+n)/r*100));i>this.scrollDepth&&(this.scrollDepth=i)};this.scrollHandler=e,e(),window.addEventListener(`scroll`,e,{passive:!0})}startHeartbeat(){this.stopHeartbeat(),this.heartbeatTimer=setInterval(()=>{if(document.visibilityState===`hidden`){this.stopHeartbeat();return}e()},300*1e3)}navigate(){!this.started||this.destroyed||(this.stopNavigationTimer(),this.navTimer=setTimeout(()=>{this.navTimer=null;let e=location.pathname!==this.pagePath,t=(this.options.trackHash??!1)&&location.hash!==this.pageHash;!e&&!t||(this.leavePage(),this.enterPage(),this.trackScroll(),this.pageview({trigger:`navigation`}))},300))}links(){let e=e=>{let t=E(e.target);t&&t.host!==location.host&&this.track(`outbound_link`,{outbound_link:t.href})};this.addDocumentListener(`click`,e),this.addDocumentListener(`auxclick`,e)}};export{y as a,C as c,_ as d,p as f,w as i,T as l,g as n,x as o,v as r,S as s,O as t,b as u};
|