@@ -2,7 +2,7 @@ import { getAnalyticsConnector, getGlobalScope } from '@amplitude/analytics-clie
2
2
import { Logger , returnWrapper } from '@amplitude/analytics-core' ;
3
3
import { Logger as ILogger } from '@amplitude/analytics-types' ;
4
4
import { pack , record } from '@amplitude/rrweb' ;
5
- import { TargetingParameters } from '@amplitude/targeting' ;
5
+ import { TargetingParameters , evaluateTargeting } from '@amplitude/targeting' ;
6
6
import { createSessionReplayJoinedConfigGenerator } from './config/joined-config' ;
7
7
import { SessionReplayJoinedConfig , SessionReplayJoinedConfigGenerator } from './config/types' ;
8
8
import {
@@ -14,11 +14,10 @@ import {
14
14
import { createEventsManager } from './events/events-manager' ;
15
15
import { generateHashCode , isSessionInSample , maskFn } from './helpers' ;
16
16
import { SessionIdentifiers } from './identifiers' ;
17
+ import * as TargetingIDBStore from './targeting-idb-store' ;
17
18
import {
18
19
AmplitudeSessionReplay ,
19
20
SessionReplayEventsManager as AmplitudeSessionReplayEventsManager ,
20
- SessionReplayRemoteConfigFetch as AmplitudeSessionReplayRemoteConfigFetch ,
21
- SessionReplaySessionIDBStore as AmplitudeSessionReplaySessionIDBStore ,
22
21
SessionIdentifiers as ISessionIdentifiers ,
23
22
SessionReplayOptions ,
24
23
} from './typings/session-replay' ;
@@ -28,11 +27,10 @@ export class SessionReplay implements AmplitudeSessionReplay {
28
27
config : SessionReplayJoinedConfig | undefined ;
29
28
joinedConfigGenerator : SessionReplayJoinedConfigGenerator | undefined ;
30
29
identifiers : ISessionIdentifiers | undefined ;
31
- remoteConfigFetch : AmplitudeSessionReplayRemoteConfigFetch | undefined ;
32
30
eventsManager : AmplitudeSessionReplayEventsManager | undefined ;
33
- sessionIDBStore : AmplitudeSessionReplaySessionIDBStore | undefined ;
34
31
loggerProvider : ILogger ;
35
32
recordCancelCallback : ReturnType < typeof record > | null = null ;
33
+ sessionTargetingMatch = false ;
36
34
37
35
constructor ( ) {
38
36
this . loggerProvider = new Logger ( ) ;
@@ -104,7 +102,7 @@ export class SessionReplay implements AmplitudeSessionReplay {
104
102
}
105
103
106
104
if ( globalScope && globalScope . document && globalScope . document . hasFocus ( ) ) {
107
- this . initialize ( true ) ;
105
+ await this . initialize ( true ) ;
108
106
}
109
107
}
110
108
@@ -171,20 +169,51 @@ export class SessionReplay implements AmplitudeSessionReplay {
171
169
} ;
172
170
173
171
focusListener = ( ) => {
174
- this . initialize ( ) ;
172
+ void this . initialize ( ) ;
175
173
} ;
176
174
177
175
evaluateTargeting = async ( targetingParams ?: Pick < TargetingParameters , 'event' | 'userProperties' > ) => {
178
- if ( ! this . identifiers || ! this . identifiers . sessionId || ! this . remoteConfigFetch || ! this . config ) {
176
+ if ( ! this . identifiers || ! this . identifiers . sessionId || ! this . config ) {
179
177
this . loggerProvider . error ( 'Session replay init has not been called, cannot evaluate targeting.' ) ;
180
178
return ;
181
179
}
182
180
183
- await this . remoteConfigFetch . evaluateTargeting ( {
181
+ const idbTargetingMatch = await TargetingIDBStore . getTargetingMatchForSession ( {
182
+ loggerProvider : this . config . loggerProvider ,
183
+ apiKey : this . config . apiKey ,
184
184
sessionId : this . identifiers . sessionId ,
185
- deviceId : this . getDeviceId ( ) ,
186
- ...targetingParams ,
187
185
} ) ;
186
+ if ( idbTargetingMatch === true ) {
187
+ this . sessionTargetingMatch = true ;
188
+ return ;
189
+ }
190
+
191
+ // Finally evaluate targeting if previous two checks were false or undefined
192
+ try {
193
+ if ( this . config . targetingConfig ) {
194
+ const targetingResult = evaluateTargeting ( {
195
+ ...targetingParams ,
196
+ flag : this . config . targetingConfig ,
197
+ sessionId : this . identifiers . sessionId ,
198
+ } ) ;
199
+ this . sessionTargetingMatch =
200
+ this . sessionTargetingMatch === false && targetingResult . sr_targeting_config . key === 'on' ;
201
+ } else {
202
+ // If the targeting config is undefined or an empty object,
203
+ // assume the response was valid but no conditions were set,
204
+ // so all users match targeting
205
+ this . sessionTargetingMatch = true ;
206
+ }
207
+ void TargetingIDBStore . storeTargetingMatchForSession ( {
208
+ loggerProvider : this . config . loggerProvider ,
209
+ apiKey : this . config . apiKey ,
210
+ sessionId : this . identifiers . sessionId ,
211
+ targetingMatch : this . sessionTargetingMatch ,
212
+ } ) ;
213
+ } catch ( err : unknown ) {
214
+ const knownError = err as Error ;
215
+ this . config . loggerProvider . warn ( knownError . message ) ;
216
+ }
188
217
} ;
189
218
190
219
stopRecordingAndSendEvents ( sessionId ?: number ) {
@@ -198,7 +227,7 @@ export class SessionReplay implements AmplitudeSessionReplay {
198
227
this . eventsManager . sendCurrentSequenceEvents ( { sessionId : sessionIdToSend , deviceId } ) ;
199
228
}
200
229
201
- initialize ( shouldSendStoredEvents = false ) {
230
+ async initialize ( shouldSendStoredEvents = false ) {
202
231
if ( ! this . identifiers ?. sessionId ) {
203
232
this . loggerProvider . log ( `Session is not being recorded due to lack of session id.` ) ;
204
233
return ;
0 commit comments