swetrix 3.7.2 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esnext/Lib.d.ts +148 -0
- package/dist/esnext/Lib.js +262 -0
- package/dist/esnext/Lib.js.map +1 -1
- package/dist/esnext/index.d.ts +146 -2
- package/dist/esnext/index.js +176 -0
- package/dist/esnext/index.js.map +1 -1
- package/dist/swetrix.cjs.js +457 -4
- package/dist/swetrix.cjs.js.map +1 -1
- package/dist/swetrix.es5.js +450 -5
- package/dist/swetrix.es5.js.map +1 -1
- package/dist/swetrix.js +1 -1
- package/dist/swetrix.js.map +1 -1
- package/package.json +1 -1
- package/src/Lib.ts +344 -1
- package/src/index.ts +202 -0
- package/tests/experiments.test.ts +330 -0
package/dist/swetrix.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"swetrix.js","sources":["../src/utils.ts","../src/Lib.ts","../src/index.ts"],"sourcesContent":[null,null,null],"names":["findInSearch","exp","res","location","search","match","undefined","utmSourceRegex","utmCampaignRegex","utmMediumRegex","utmTermRegex","utmContentRegex","getLocale","navigator","languages","language","getTimezone","Intl","DateTimeFormat","resolvedOptions","timeZone","e","getReferrer","document","referrer","getUTMSource","getUTMMedium","getUTMCampaign","getUTMTerm","getUTMContent","getPath","options","result","pathname","hash","hashIndex","indexOf","substring","defaultActions","stop","Lib","constructor","projectID","this","pageData","pageViewsOptions","errorsOptions","perfStatsCollected","activePage","errorListenerExists","trackPathChange","bind","heartbeat","captureError","event","_a","sampleRate","Math","random","submitError","filename","lineno","colno","name","_b","error","message","_c","stackTrace","_d","stack","trackErrors","canTrack","window","addEventListener","removeEventListener","payload","evokeCallback","privateData","pid","errorPayload","pg","lc","tz","callback","callbackResult","Object","assign","sendRequest","track","data","ref","so","me","ca","te","co","trackPageViews","actions","interval","unique","setInterval","setTimeout","hbInterval","path","clearInterval","trackPage","getPerformanceStats","performance","getEntriesByType","perf","dns","domainLookupEnd","domainLookupStart","tls","secureConnectionStart","requestStart","conn","connectStart","connectEnd","response","responseEnd","responseStart","render","domComplete","domContentLoadedEventEnd","dom_load","page_load","loadEventStart","ttfb","heartbeatOnBackground","visibilityState","newPath","submitPageView","pvPayload","disabled","respectDNT","doNotTrack","devMode","hostname","webdriver","body","host","apiURL","fetch","method","headers","JSON","stringify","LIB_INSTANCE","Boolean","async","_prev","Promise","resolve","readyState"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"swetrix.js","sources":["../src/utils.ts","../src/Lib.ts","../src/index.ts"],"sourcesContent":[null,null,null],"names":["findInSearch","exp","res","location","search","match","undefined","utmSourceRegex","utmCampaignRegex","utmMediumRegex","utmTermRegex","utmContentRegex","isInBrowser","window","getLocale","navigator","languages","language","getTimezone","Intl","DateTimeFormat","resolvedOptions","timeZone","e","getReferrer","document","referrer","getUTMSource","getUTMMedium","getUTMCampaign","getUTMTerm","getUTMContent","getPath","options","result","pathname","hash","hashIndex","indexOf","substring","defaultActions","stop","DEFAULT_CACHE_DURATION","Lib","constructor","projectID","this","pageData","pageViewsOptions","errorsOptions","perfStatsCollected","activePage","errorListenerExists","cachedData","trackPathChange","bind","heartbeat","captureError","event","_a","sampleRate","Math","random","submitError","filename","lineno","colno","name","_b","error","message","_c","stackTrace","_d","stack","trackErrors","canTrack","addEventListener","removeEventListener","payload","evokeCallback","privateData","pid","errorPayload","pg","lc","tz","callback","callbackResult","Object","assign","sendRequest","track","data","ref","so","me","ca","te","co","profileId","trackPageViews","actions","interval","unique","setInterval","setTimeout","hbInterval","path","clearInterval","trackPage","getPerformanceStats","performance","getEntriesByType","perf","dns","domainLookupEnd","domainLookupStart","tls","secureConnectionStart","requestStart","conn","connectStart","connectEnd","response","responseEnd","responseStart","render","domComplete","domContentLoadedEventEnd","dom_load","page_load","loadEventStart","ttfb","getFeatureFlags","forceRefresh","requestedProfileId","now","Date","timestamp","flags","fetchFlagsAndExperiments","console","warn","apiBase","getApiBase","body","fetch","method","headers","JSON","stringify","ok","status","json","cachedProfileId","experiments","getFeatureFlag","key","defaultValue","clearFeatureFlagsCache","getExperiments","getExperiment","experimentId","defaultVariant","clearExperimentsCache","getProfileId","getSessionId","sessionId","apiURL","replace","heartbeatOnBackground","visibilityState","newPath","submitPageView","pvPayload","disabled","respectDNT","doNotTrack","devMode","hostname","webdriver","host","LIB_INSTANCE","async","Boolean","_prev","Promise","resolve","readyState"],"mappings":"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"}
|
package/package.json
CHANGED
package/src/Lib.ts
CHANGED
|
@@ -32,6 +32,12 @@ export interface LibOptions {
|
|
|
32
32
|
|
|
33
33
|
/** Set a custom URL of the API server (for selfhosted variants of Swetrix). */
|
|
34
34
|
apiURL?: string
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Optional profile ID for long-term user tracking.
|
|
38
|
+
* If set, it will be used for all pageviews and events unless overridden per-call.
|
|
39
|
+
*/
|
|
40
|
+
profileId?: string
|
|
35
41
|
}
|
|
36
42
|
|
|
37
43
|
export interface TrackEventOptions {
|
|
@@ -45,6 +51,9 @@ export interface TrackEventOptions {
|
|
|
45
51
|
meta?: {
|
|
46
52
|
[key: string]: string | number | boolean | null | undefined
|
|
47
53
|
}
|
|
54
|
+
|
|
55
|
+
/** Optional profile ID for long-term user tracking. Overrides the global profileId if set. */
|
|
56
|
+
profileId?: string
|
|
48
57
|
}
|
|
49
58
|
|
|
50
59
|
// Partial user-editable pageview payload
|
|
@@ -63,6 +72,9 @@ export interface IPageViewPayload {
|
|
|
63
72
|
meta?: {
|
|
64
73
|
[key: string]: string | number | boolean | null | undefined
|
|
65
74
|
}
|
|
75
|
+
|
|
76
|
+
/** Optional profile ID for long-term user tracking. Overrides the global profileId if set. */
|
|
77
|
+
profileId?: string
|
|
66
78
|
}
|
|
67
79
|
|
|
68
80
|
// Partial user-editable error payload
|
|
@@ -95,6 +107,41 @@ interface IPerfPayload {
|
|
|
95
107
|
ttfb: number
|
|
96
108
|
}
|
|
97
109
|
|
|
110
|
+
/**
|
|
111
|
+
* Options for evaluating feature flags.
|
|
112
|
+
*/
|
|
113
|
+
export interface FeatureFlagsOptions {
|
|
114
|
+
/**
|
|
115
|
+
* Optional profile ID for long-term user tracking.
|
|
116
|
+
* If not provided, an anonymous profile ID will be generated server-side based on IP and user agent.
|
|
117
|
+
* Overrides the global profileId if set.
|
|
118
|
+
*/
|
|
119
|
+
profileId?: string
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Options for evaluating experiments.
|
|
124
|
+
*/
|
|
125
|
+
export interface ExperimentOptions {
|
|
126
|
+
/**
|
|
127
|
+
* Optional profile ID for long-term user tracking.
|
|
128
|
+
* If not provided, an anonymous profile ID will be generated server-side based on IP and user agent.
|
|
129
|
+
* Overrides the global profileId if set.
|
|
130
|
+
*/
|
|
131
|
+
profileId?: string
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Cached feature flags and experiments with timestamp.
|
|
136
|
+
*/
|
|
137
|
+
interface CachedData {
|
|
138
|
+
flags: Record<string, boolean>
|
|
139
|
+
experiments: Record<string, string>
|
|
140
|
+
timestamp: number
|
|
141
|
+
/** The profileId used when fetching this cached data */
|
|
142
|
+
profileId?: string
|
|
143
|
+
}
|
|
144
|
+
|
|
98
145
|
/**
|
|
99
146
|
* The object returned by `trackPageViews()`, used to stop tracking pages.
|
|
100
147
|
*/
|
|
@@ -174,6 +221,10 @@ export const defaultActions = {
|
|
|
174
221
|
}
|
|
175
222
|
|
|
176
223
|
const DEFAULT_API_HOST = 'https://api.swetrix.com/log'
|
|
224
|
+
const DEFAULT_API_BASE = 'https://api.swetrix.com'
|
|
225
|
+
|
|
226
|
+
// Default cache duration: 5 minutes
|
|
227
|
+
const DEFAULT_CACHE_DURATION = 5 * 60 * 1000
|
|
177
228
|
|
|
178
229
|
export class Lib {
|
|
179
230
|
private pageData: PageData | null = null
|
|
@@ -182,6 +233,7 @@ export class Lib {
|
|
|
182
233
|
private perfStatsCollected: boolean = false
|
|
183
234
|
private activePage: string | null = null
|
|
184
235
|
private errorListenerExists = false
|
|
236
|
+
private cachedData: CachedData | null = null
|
|
185
237
|
|
|
186
238
|
constructor(private projectID: string, private options?: LibOptions) {
|
|
187
239
|
this.trackPathChange = this.trackPathChange.bind(this)
|
|
@@ -294,6 +346,7 @@ export class Lib {
|
|
|
294
346
|
ca: getUTMCampaign(),
|
|
295
347
|
te: getUTMTerm(),
|
|
296
348
|
co: getUTMContent(),
|
|
349
|
+
profileId: event.profileId ?? this.options?.profileId,
|
|
297
350
|
}
|
|
298
351
|
await this.sendRequest('custom', data)
|
|
299
352
|
}
|
|
@@ -368,15 +421,304 @@ export class Lib {
|
|
|
368
421
|
}
|
|
369
422
|
}
|
|
370
423
|
|
|
424
|
+
/**
|
|
425
|
+
* Fetches all feature flags and experiments for the project.
|
|
426
|
+
* Results are cached for 5 minutes by default.
|
|
427
|
+
*
|
|
428
|
+
* @param options - Options for evaluating feature flags.
|
|
429
|
+
* @param forceRefresh - If true, bypasses the cache and fetches fresh data.
|
|
430
|
+
* @returns A promise that resolves to a record of flag keys to boolean values.
|
|
431
|
+
*/
|
|
432
|
+
async getFeatureFlags(options?: FeatureFlagsOptions, forceRefresh?: boolean): Promise<Record<string, boolean>> {
|
|
433
|
+
if (!isInBrowser()) {
|
|
434
|
+
return {}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
const requestedProfileId = options?.profileId ?? this.options?.profileId
|
|
438
|
+
|
|
439
|
+
// Check cache first - must match profileId and not be expired
|
|
440
|
+
if (!forceRefresh && this.cachedData) {
|
|
441
|
+
const now = Date.now()
|
|
442
|
+
const isSameProfile = this.cachedData.profileId === requestedProfileId
|
|
443
|
+
if (isSameProfile && now - this.cachedData.timestamp < DEFAULT_CACHE_DURATION) {
|
|
444
|
+
return this.cachedData.flags
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
try {
|
|
449
|
+
await this.fetchFlagsAndExperiments(options)
|
|
450
|
+
return this.cachedData?.flags || {}
|
|
451
|
+
} catch (error) {
|
|
452
|
+
console.warn('[Swetrix] Error fetching feature flags:', error)
|
|
453
|
+
return this.cachedData?.flags || {}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Internal method to fetch both feature flags and experiments from the API.
|
|
459
|
+
*/
|
|
460
|
+
private async fetchFlagsAndExperiments(options?: FeatureFlagsOptions | ExperimentOptions): Promise<void> {
|
|
461
|
+
const apiBase = this.getApiBase()
|
|
462
|
+
const body: { pid: string; profileId?: string } = {
|
|
463
|
+
pid: this.projectID,
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// Use profileId from options, or fall back to global profileId
|
|
467
|
+
const profileId = options?.profileId ?? this.options?.profileId
|
|
468
|
+
if (profileId) {
|
|
469
|
+
body.profileId = profileId
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
const response = await fetch(`${apiBase}/feature-flag/evaluate`, {
|
|
473
|
+
method: 'POST',
|
|
474
|
+
headers: {
|
|
475
|
+
'Content-Type': 'application/json',
|
|
476
|
+
},
|
|
477
|
+
body: JSON.stringify(body),
|
|
478
|
+
})
|
|
479
|
+
|
|
480
|
+
if (!response.ok) {
|
|
481
|
+
console.warn('[Swetrix] Failed to fetch feature flags and experiments:', response.status)
|
|
482
|
+
return
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
const data = (await response.json()) as {
|
|
486
|
+
flags: Record<string, boolean>
|
|
487
|
+
experiments?: Record<string, string>
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// Use profileId from options, or fall back to global profileId
|
|
491
|
+
const cachedProfileId = options?.profileId ?? this.options?.profileId
|
|
492
|
+
|
|
493
|
+
// Update cache with both flags and experiments
|
|
494
|
+
this.cachedData = {
|
|
495
|
+
flags: data.flags || {},
|
|
496
|
+
experiments: data.experiments || {},
|
|
497
|
+
timestamp: Date.now(),
|
|
498
|
+
profileId: cachedProfileId,
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Gets the value of a single feature flag.
|
|
504
|
+
*
|
|
505
|
+
* @param key - The feature flag key.
|
|
506
|
+
* @param options - Options for evaluating the feature flag.
|
|
507
|
+
* @param defaultValue - Default value to return if the flag is not found. Defaults to false.
|
|
508
|
+
* @returns A promise that resolves to the boolean value of the flag.
|
|
509
|
+
*/
|
|
510
|
+
async getFeatureFlag(key: string, options?: FeatureFlagsOptions, defaultValue: boolean = false): Promise<boolean> {
|
|
511
|
+
const flags = await this.getFeatureFlags(options)
|
|
512
|
+
return flags[key] ?? defaultValue
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* Clears the cached feature flags and experiments, forcing a fresh fetch on the next call.
|
|
517
|
+
*/
|
|
518
|
+
clearFeatureFlagsCache(): void {
|
|
519
|
+
this.cachedData = null
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* Fetches all A/B test experiments for the project.
|
|
524
|
+
* Results are cached for 5 minutes by default (shared cache with feature flags).
|
|
525
|
+
*
|
|
526
|
+
* @param options - Options for evaluating experiments.
|
|
527
|
+
* @param forceRefresh - If true, bypasses the cache and fetches fresh data.
|
|
528
|
+
* @returns A promise that resolves to a record of experiment IDs to variant keys.
|
|
529
|
+
*
|
|
530
|
+
* @example
|
|
531
|
+
* ```typescript
|
|
532
|
+
* const experiments = await getExperiments()
|
|
533
|
+
* // experiments = { 'exp-123': 'variant-a', 'exp-456': 'control' }
|
|
534
|
+
* ```
|
|
535
|
+
*/
|
|
536
|
+
async getExperiments(options?: ExperimentOptions, forceRefresh?: boolean): Promise<Record<string, string>> {
|
|
537
|
+
if (!isInBrowser()) {
|
|
538
|
+
return {}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
const requestedProfileId = options?.profileId ?? this.options?.profileId
|
|
542
|
+
|
|
543
|
+
// Check cache first - must match profileId and not be expired
|
|
544
|
+
if (!forceRefresh && this.cachedData) {
|
|
545
|
+
const now = Date.now()
|
|
546
|
+
const isSameProfile = this.cachedData.profileId === requestedProfileId
|
|
547
|
+
if (isSameProfile && now - this.cachedData.timestamp < DEFAULT_CACHE_DURATION) {
|
|
548
|
+
return this.cachedData.experiments
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
try {
|
|
553
|
+
await this.fetchFlagsAndExperiments(options)
|
|
554
|
+
return this.cachedData?.experiments || {}
|
|
555
|
+
} catch (error) {
|
|
556
|
+
console.warn('[Swetrix] Error fetching experiments:', error)
|
|
557
|
+
return this.cachedData?.experiments || {}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* Gets the variant key for a specific A/B test experiment.
|
|
563
|
+
*
|
|
564
|
+
* @param experimentId - The experiment ID.
|
|
565
|
+
* @param options - Options for evaluating the experiment.
|
|
566
|
+
* @param defaultVariant - Default variant key to return if the experiment is not found. Defaults to null.
|
|
567
|
+
* @returns A promise that resolves to the variant key assigned to this user, or defaultVariant if not found.
|
|
568
|
+
*
|
|
569
|
+
* @example
|
|
570
|
+
* ```typescript
|
|
571
|
+
* const variant = await getExperiment('checkout-redesign')
|
|
572
|
+
*
|
|
573
|
+
* if (variant === 'new-checkout') {
|
|
574
|
+
* // Show new checkout flow
|
|
575
|
+
* } else {
|
|
576
|
+
* // Show control (original) checkout
|
|
577
|
+
* }
|
|
578
|
+
* ```
|
|
579
|
+
*/
|
|
580
|
+
async getExperiment(
|
|
581
|
+
experimentId: string,
|
|
582
|
+
options?: ExperimentOptions,
|
|
583
|
+
defaultVariant: string | null = null,
|
|
584
|
+
): Promise<string | null> {
|
|
585
|
+
const experiments = await this.getExperiments(options)
|
|
586
|
+
return experiments[experimentId] ?? defaultVariant
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* Clears the cached experiments (alias for clearFeatureFlagsCache since they share the same cache).
|
|
591
|
+
*/
|
|
592
|
+
clearExperimentsCache(): void {
|
|
593
|
+
this.cachedData = null
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
/**
|
|
597
|
+
* Gets the anonymous profile ID for the current visitor.
|
|
598
|
+
* If profileId was set via init options, returns that.
|
|
599
|
+
* Otherwise, requests server to generate one from IP/UA hash.
|
|
600
|
+
*
|
|
601
|
+
* This ID can be used for revenue attribution with payment providers.
|
|
602
|
+
*
|
|
603
|
+
* @returns A promise that resolves to the profile ID string, or null on error.
|
|
604
|
+
*
|
|
605
|
+
* @example
|
|
606
|
+
* ```typescript
|
|
607
|
+
* const profileId = await swetrix.getProfileId()
|
|
608
|
+
*
|
|
609
|
+
* // Pass to Paddle Checkout for revenue attribution
|
|
610
|
+
* Paddle.Checkout.open({
|
|
611
|
+
* items: [{ priceId: 'pri_01234567890', quantity: 1 }],
|
|
612
|
+
* customData: {
|
|
613
|
+
* swetrix_profile_id: profileId,
|
|
614
|
+
* swetrix_session_id: await swetrix.getSessionId()
|
|
615
|
+
* }
|
|
616
|
+
* })
|
|
617
|
+
* ```
|
|
618
|
+
*/
|
|
619
|
+
async getProfileId(): Promise<string | null> {
|
|
620
|
+
// If profileId is already set in options, return it
|
|
621
|
+
if (this.options?.profileId) {
|
|
622
|
+
return this.options.profileId
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
if (!isInBrowser()) {
|
|
626
|
+
return null
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
try {
|
|
630
|
+
const apiBase = this.getApiBase()
|
|
631
|
+
const response = await fetch(`${apiBase}/log/profile-id`, {
|
|
632
|
+
method: 'POST',
|
|
633
|
+
headers: {
|
|
634
|
+
'Content-Type': 'application/json',
|
|
635
|
+
},
|
|
636
|
+
body: JSON.stringify({ pid: this.projectID }),
|
|
637
|
+
})
|
|
638
|
+
|
|
639
|
+
if (!response.ok) {
|
|
640
|
+
return null
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
const data = (await response.json()) as { profileId: string | null }
|
|
644
|
+
return data.profileId
|
|
645
|
+
} catch {
|
|
646
|
+
return null
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Gets the current session ID for the visitor.
|
|
652
|
+
* Session IDs are generated server-side based on IP and user agent.
|
|
653
|
+
*
|
|
654
|
+
* This ID can be used for revenue attribution with payment providers.
|
|
655
|
+
*
|
|
656
|
+
* @returns A promise that resolves to the session ID string, or null on error.
|
|
657
|
+
*
|
|
658
|
+
* @example
|
|
659
|
+
* ```typescript
|
|
660
|
+
* const sessionId = await swetrix.getSessionId()
|
|
661
|
+
*
|
|
662
|
+
* // Pass to Paddle Checkout for revenue attribution
|
|
663
|
+
* Paddle.Checkout.open({
|
|
664
|
+
* items: [{ priceId: 'pri_01234567890', quantity: 1 }],
|
|
665
|
+
* customData: {
|
|
666
|
+
* swetrix_profile_id: await swetrix.getProfileId(),
|
|
667
|
+
* swetrix_session_id: sessionId
|
|
668
|
+
* }
|
|
669
|
+
* })
|
|
670
|
+
* ```
|
|
671
|
+
*/
|
|
672
|
+
async getSessionId(): Promise<string | null> {
|
|
673
|
+
if (!isInBrowser()) {
|
|
674
|
+
return null
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
try {
|
|
678
|
+
const apiBase = this.getApiBase()
|
|
679
|
+
const response = await fetch(`${apiBase}/log/session-id`, {
|
|
680
|
+
method: 'POST',
|
|
681
|
+
headers: {
|
|
682
|
+
'Content-Type': 'application/json',
|
|
683
|
+
},
|
|
684
|
+
body: JSON.stringify({ pid: this.projectID }),
|
|
685
|
+
})
|
|
686
|
+
|
|
687
|
+
if (!response.ok) {
|
|
688
|
+
return null
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
const data = (await response.json()) as { sessionId: string | null }
|
|
692
|
+
return data.sessionId
|
|
693
|
+
} catch {
|
|
694
|
+
return null
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
/**
|
|
699
|
+
* Gets the API base URL (without /log suffix).
|
|
700
|
+
*/
|
|
701
|
+
private getApiBase(): string {
|
|
702
|
+
if (this.options?.apiURL) {
|
|
703
|
+
// Remove trailing /log if present
|
|
704
|
+
return this.options.apiURL.replace(/\/log\/?$/, '')
|
|
705
|
+
}
|
|
706
|
+
return DEFAULT_API_BASE
|
|
707
|
+
}
|
|
708
|
+
|
|
371
709
|
private heartbeat(): void {
|
|
372
710
|
if (!this.pageViewsOptions?.heartbeatOnBackground && document.visibilityState === 'hidden') {
|
|
373
711
|
return
|
|
374
712
|
}
|
|
375
713
|
|
|
376
|
-
const data = {
|
|
714
|
+
const data: { pid: string; profileId?: string } = {
|
|
377
715
|
pid: this.projectID,
|
|
378
716
|
}
|
|
379
717
|
|
|
718
|
+
if (this.options?.profileId) {
|
|
719
|
+
data.profileId = this.options.profileId
|
|
720
|
+
}
|
|
721
|
+
|
|
380
722
|
this.sendRequest('hb', data)
|
|
381
723
|
}
|
|
382
724
|
|
|
@@ -425,6 +767,7 @@ export class Lib {
|
|
|
425
767
|
ca: getUTMCampaign(),
|
|
426
768
|
te: getUTMTerm(),
|
|
427
769
|
co: getUTMContent(),
|
|
770
|
+
profileId: this.options?.profileId,
|
|
428
771
|
...payload,
|
|
429
772
|
}
|
|
430
773
|
|
package/src/index.ts
CHANGED
|
@@ -9,6 +9,8 @@ import {
|
|
|
9
9
|
defaultActions,
|
|
10
10
|
IErrorEventPayload,
|
|
11
11
|
IPageViewPayload,
|
|
12
|
+
FeatureFlagsOptions,
|
|
13
|
+
ExperimentOptions,
|
|
12
14
|
} from './Lib.js'
|
|
13
15
|
|
|
14
16
|
export let LIB_INSTANCE: Lib | null = null
|
|
@@ -120,6 +122,204 @@ export function pageview(options: IPageviewOptions): void {
|
|
|
120
122
|
LIB_INSTANCE.submitPageView(options.payload, Boolean(options.unique), {})
|
|
121
123
|
}
|
|
122
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Fetches all feature flags for the project.
|
|
127
|
+
* Results are cached for 5 minutes by default.
|
|
128
|
+
*
|
|
129
|
+
* @param options - Options for evaluating feature flags (visitorId, attributes).
|
|
130
|
+
* @param forceRefresh - If true, bypasses the cache and fetches fresh flags.
|
|
131
|
+
* @returns A promise that resolves to a record of flag keys to boolean values.
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```typescript
|
|
135
|
+
* const flags = await getFeatureFlags({
|
|
136
|
+
* visitorId: 'user-123',
|
|
137
|
+
* attributes: { cc: 'US', dv: 'desktop' }
|
|
138
|
+
* })
|
|
139
|
+
*
|
|
140
|
+
* if (flags['new-checkout']) {
|
|
141
|
+
* // Show new checkout flow
|
|
142
|
+
* }
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
export async function getFeatureFlags(
|
|
146
|
+
options?: FeatureFlagsOptions,
|
|
147
|
+
forceRefresh?: boolean,
|
|
148
|
+
): Promise<Record<string, boolean>> {
|
|
149
|
+
if (!LIB_INSTANCE) return {}
|
|
150
|
+
|
|
151
|
+
return LIB_INSTANCE.getFeatureFlags(options, forceRefresh)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Gets the value of a single feature flag.
|
|
156
|
+
*
|
|
157
|
+
* @param key - The feature flag key.
|
|
158
|
+
* @param options - Options for evaluating the feature flag (visitorId, attributes).
|
|
159
|
+
* @param defaultValue - Default value to return if the flag is not found. Defaults to false.
|
|
160
|
+
* @returns A promise that resolves to the boolean value of the flag.
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```typescript
|
|
164
|
+
* const isEnabled = await getFeatureFlag('dark-mode', { visitorId: 'user-123' })
|
|
165
|
+
*
|
|
166
|
+
* if (isEnabled) {
|
|
167
|
+
* // Enable dark mode
|
|
168
|
+
* }
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
171
|
+
export async function getFeatureFlag(
|
|
172
|
+
key: string,
|
|
173
|
+
options?: FeatureFlagsOptions,
|
|
174
|
+
defaultValue: boolean = false,
|
|
175
|
+
): Promise<boolean> {
|
|
176
|
+
if (!LIB_INSTANCE) return defaultValue
|
|
177
|
+
|
|
178
|
+
return LIB_INSTANCE.getFeatureFlag(key, options, defaultValue)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Clears the cached feature flags, forcing a fresh fetch on the next call.
|
|
183
|
+
* Useful when you know the user's context has changed significantly.
|
|
184
|
+
*/
|
|
185
|
+
export function clearFeatureFlagsCache(): void {
|
|
186
|
+
if (!LIB_INSTANCE) return
|
|
187
|
+
|
|
188
|
+
LIB_INSTANCE.clearFeatureFlagsCache()
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Fetches all A/B test experiments for the project.
|
|
193
|
+
* Results are cached for 5 minutes by default (shared cache with feature flags).
|
|
194
|
+
*
|
|
195
|
+
* @param options - Options for evaluating experiments.
|
|
196
|
+
* @param forceRefresh - If true, bypasses the cache and fetches fresh data.
|
|
197
|
+
* @returns A promise that resolves to a record of experiment IDs to variant keys.
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```typescript
|
|
201
|
+
* const experiments = await getExperiments()
|
|
202
|
+
* // experiments = { 'exp-123': 'variant-a', 'exp-456': 'control' }
|
|
203
|
+
*
|
|
204
|
+
* // Use the assigned variant
|
|
205
|
+
* const checkoutVariant = experiments['checkout-experiment-id']
|
|
206
|
+
* if (checkoutVariant === 'new-checkout') {
|
|
207
|
+
* showNewCheckout()
|
|
208
|
+
* } else {
|
|
209
|
+
* showOriginalCheckout()
|
|
210
|
+
* }
|
|
211
|
+
* ```
|
|
212
|
+
*/
|
|
213
|
+
export async function getExperiments(
|
|
214
|
+
options?: ExperimentOptions,
|
|
215
|
+
forceRefresh?: boolean,
|
|
216
|
+
): Promise<Record<string, string>> {
|
|
217
|
+
if (!LIB_INSTANCE) return {}
|
|
218
|
+
|
|
219
|
+
return LIB_INSTANCE.getExperiments(options, forceRefresh)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Gets the variant key for a specific A/B test experiment.
|
|
224
|
+
*
|
|
225
|
+
* @param experimentId - The experiment ID.
|
|
226
|
+
* @param options - Options for evaluating the experiment.
|
|
227
|
+
* @param defaultVariant - Default variant key to return if the experiment is not found. Defaults to null.
|
|
228
|
+
* @returns A promise that resolves to the variant key assigned to this user, or defaultVariant if not found.
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```typescript
|
|
232
|
+
* const variant = await getExperiment('checkout-redesign-experiment-id')
|
|
233
|
+
*
|
|
234
|
+
* if (variant === 'new-checkout') {
|
|
235
|
+
* // Show new checkout flow
|
|
236
|
+
* showNewCheckout()
|
|
237
|
+
* } else if (variant === 'control') {
|
|
238
|
+
* // Show original checkout (control group)
|
|
239
|
+
* showOriginalCheckout()
|
|
240
|
+
* } else {
|
|
241
|
+
* // Experiment not running or user not included
|
|
242
|
+
* showOriginalCheckout()
|
|
243
|
+
* }
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
export async function getExperiment(
|
|
247
|
+
experimentId: string,
|
|
248
|
+
options?: ExperimentOptions,
|
|
249
|
+
defaultVariant: string | null = null,
|
|
250
|
+
): Promise<string | null> {
|
|
251
|
+
if (!LIB_INSTANCE) return defaultVariant
|
|
252
|
+
|
|
253
|
+
return LIB_INSTANCE.getExperiment(experimentId, options, defaultVariant)
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Clears the cached experiments, forcing a fresh fetch on the next call.
|
|
258
|
+
* This is an alias for clearFeatureFlagsCache since experiments and flags share the same cache.
|
|
259
|
+
*/
|
|
260
|
+
export function clearExperimentsCache(): void {
|
|
261
|
+
if (!LIB_INSTANCE) return
|
|
262
|
+
|
|
263
|
+
LIB_INSTANCE.clearExperimentsCache()
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Gets the anonymous profile ID for the current visitor.
|
|
268
|
+
* If profileId was set via init options, returns that.
|
|
269
|
+
* Otherwise, requests server to generate one from IP/UA hash.
|
|
270
|
+
*
|
|
271
|
+
* This ID can be used for revenue attribution with payment providers like Paddle.
|
|
272
|
+
*
|
|
273
|
+
* @returns A promise that resolves to the profile ID string, or null on error.
|
|
274
|
+
*
|
|
275
|
+
* @example
|
|
276
|
+
* ```typescript
|
|
277
|
+
* const profileId = await getProfileId()
|
|
278
|
+
*
|
|
279
|
+
* // Pass to Paddle Checkout for revenue attribution
|
|
280
|
+
* Paddle.Checkout.open({
|
|
281
|
+
* items: [{ priceId: 'pri_01234567890', quantity: 1 }],
|
|
282
|
+
* customData: {
|
|
283
|
+
* swetrix_profile_id: profileId,
|
|
284
|
+
* swetrix_session_id: await getSessionId()
|
|
285
|
+
* }
|
|
286
|
+
* })
|
|
287
|
+
* ```
|
|
288
|
+
*/
|
|
289
|
+
export async function getProfileId(): Promise<string | null> {
|
|
290
|
+
if (!LIB_INSTANCE) return null
|
|
291
|
+
|
|
292
|
+
return LIB_INSTANCE.getProfileId()
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Gets the current session ID for the visitor.
|
|
297
|
+
* Session IDs are generated server-side based on IP and user agent.
|
|
298
|
+
*
|
|
299
|
+
* This ID can be used for revenue attribution with payment providers like Paddle.
|
|
300
|
+
*
|
|
301
|
+
* @returns A promise that resolves to the session ID string, or null on error.
|
|
302
|
+
*
|
|
303
|
+
* @example
|
|
304
|
+
* ```typescript
|
|
305
|
+
* const sessionId = await getSessionId()
|
|
306
|
+
*
|
|
307
|
+
* // Pass to Paddle Checkout for revenue attribution
|
|
308
|
+
* Paddle.Checkout.open({
|
|
309
|
+
* items: [{ priceId: 'pri_01234567890', quantity: 1 }],
|
|
310
|
+
* customData: {
|
|
311
|
+
* swetrix_profile_id: await getProfileId(),
|
|
312
|
+
* swetrix_session_id: sessionId
|
|
313
|
+
* }
|
|
314
|
+
* })
|
|
315
|
+
* ```
|
|
316
|
+
*/
|
|
317
|
+
export async function getSessionId(): Promise<string | null> {
|
|
318
|
+
if (!LIB_INSTANCE) return null
|
|
319
|
+
|
|
320
|
+
return LIB_INSTANCE.getSessionId()
|
|
321
|
+
}
|
|
322
|
+
|
|
123
323
|
export {
|
|
124
324
|
LibOptions,
|
|
125
325
|
TrackEventOptions,
|
|
@@ -129,4 +329,6 @@ export {
|
|
|
129
329
|
ErrorActions,
|
|
130
330
|
IErrorEventPayload,
|
|
131
331
|
IPageViewPayload,
|
|
332
|
+
FeatureFlagsOptions,
|
|
333
|
+
ExperimentOptions,
|
|
132
334
|
}
|