1+ import uuid from 'react-native-uuid' ;
12import OidcAuthStateStorage , {
23 type OidcAuthState ,
34} from './OidcAuthStateStorage' ;
@@ -12,16 +13,31 @@ import {
1213} from 'react-native-app-auth' ;
1314import { REFRESH_TOKEN_RETRIES , SCOPES } from './consts/oidcConsts' ;
1415import { RefreshTokenStrategy } from './types/RefreshTokenStrategy' ;
15- import fetchContentpassToken from './utils /fetchContentpassToken' ;
16- import validateSubscription from './utils /validateSubscription' ;
16+ import fetchContentpassToken from './contentpassTokenUtils /fetchContentpassToken' ;
17+ import validateSubscription from './contentpassTokenUtils /validateSubscription' ;
1718import type { ContentpassConfig } from './types/ContentpassConfig' ;
1819import { reportError , setSentryExtraAttribute } from './sentryIntegration' ;
20+ import sendStats from './countImpressionUtils/sendStats' ;
21+ import sendPageViewEvent from './countImpressionUtils/sendPageViewEvent' ;
22+
23+ const DEFAULT_FREE_IMPRESSIONS_SAMPLING_RATE = 0.01 ;
1924
2025export type ContentpassObserver = ( state : ContentpassState ) => void ;
2126
22- export default class Contentpass {
27+ interface ContentpassInterface {
28+ authenticate : ( ) => Promise < void > ;
29+ registerObserver : ( observer : ContentpassObserver ) => void ;
30+ unregisterObserver : ( observer : ContentpassObserver ) => void ;
31+ logout : ( ) => Promise < void > ;
32+ recoverFromError : ( ) => Promise < void > ;
33+ countImpression : ( ) => Promise < void > ;
34+ }
35+
36+ export default class Contentpass implements ContentpassInterface {
2337 private authStateStorage : OidcAuthStateStorage ;
2438 private readonly config : ContentpassConfig ;
39+ private readonly samplingRate : number ;
40+ private instanceId : string ;
2541
2642 private contentpassState : ContentpassState = {
2743 state : ContentpassStateType . INITIALISING ,
@@ -31,6 +47,15 @@ export default class Contentpass {
3147 private refreshTimer : NodeJS . Timeout | null = null ;
3248
3349 constructor ( config : ContentpassConfig ) {
50+ if (
51+ config . samplingRate &&
52+ ( config . samplingRate < 0 || config . samplingRate > 1 )
53+ ) {
54+ throw new Error ( 'Sampling rate must be between 0 and 1' ) ;
55+ }
56+ this . samplingRate =
57+ config . samplingRate || DEFAULT_FREE_IMPRESSIONS_SAMPLING_RATE ;
58+ this . instanceId = uuid . v4 ( ) ;
3459 this . authStateStorage = new OidcAuthStateStorage ( config . propertyId ) ;
3560 this . config = config ;
3661 setSentryExtraAttribute ( 'propertyId' , config . propertyId ) ;
@@ -96,6 +121,52 @@ export default class Contentpass {
96121 await this . initialiseAuthState ( ) ;
97122 } ;
98123
124+ public countImpression = async ( ) => {
125+ if ( this . oidcAuthState ?. accessToken ) {
126+ await this . countPaidImpression ( ) ;
127+ }
128+
129+ // always count free impression even if user is authenticated
130+ await this . countFreeImpression ( ) ;
131+ } ;
132+
133+ private countPaidImpression = async ( ) => {
134+ const impressionId = uuid . v4 ( ) ;
135+
136+ try {
137+ await sendPageViewEvent ( this . config . apiUrl , {
138+ propertyId : this . config . propertyId ,
139+ impressionId,
140+ accessToken : this . oidcAuthState ! . accessToken ,
141+ } ) ;
142+ } catch ( err : any ) {
143+ reportError ( err , { msg : 'Failed to count impression paid impression' } ) ;
144+ throw err ;
145+ }
146+ } ;
147+
148+ private countFreeImpression = async ( ) => {
149+ const generatedSample = Math . random ( ) ;
150+ const publicId = this . config . propertyId . slice ( 0 , 8 ) ;
151+
152+ if ( generatedSample >= this . samplingRate ) {
153+ return ;
154+ }
155+
156+ try {
157+ await sendStats ( this . config . apiUrl , {
158+ ea : 'load' ,
159+ ec : 'tcf-sampled' ,
160+ cpabid : this . instanceId ,
161+ cppid : publicId ,
162+ cpsr : this . samplingRate ,
163+ } ) ;
164+ } catch ( err : any ) {
165+ reportError ( err , { msg : 'Failed to count impression paid impression' } ) ;
166+ throw err ;
167+ }
168+ } ;
169+
99170 private initialiseAuthState = async ( ) => {
100171 const authState = await this . authStateStorage . getOidcAuthState ( ) ;
101172 if ( authState ) {
0 commit comments