-
Notifications
You must be signed in to change notification settings - Fork 170
Expand file tree
/
Copy pathfeatureFlagContext.ts
More file actions
72 lines (62 loc) · 2.38 KB
/
featureFlagContext.ts
File metadata and controls
72 lines (62 loc) · 2.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import type { ContextValue, Context } from '@datadog/browser-core'
import { HookNames, SESSION_TIME_OUT_DELAY, SKIPPED, createValueHistory, isEmptyObject } from '@datadog/browser-core'
import type { LifeCycle } from '../lifeCycle'
import { LifeCycleEventType } from '../lifeCycle'
import { RumEventType } from '../../rawRumEvent.types'
import type { RumConfiguration } from '../configuration'
import type { DefaultRumEventAttributes, Hooks } from '../hooks'
export const FEATURE_FLAG_CONTEXT_TIME_OUT_DELAY = SESSION_TIME_OUT_DELAY
export const BYTES_COMPUTATION_THROTTLING_DELAY = 200
export type FeatureFlagContext = Context
export interface FeatureFlagContexts {
addFeatureFlagEvaluation: (key: string, value: ContextValue) => void
}
/**
* Start feature flag contexts
*
* Feature flag contexts follow the life of views.
* A new context is added when a view is created and ended when the view is ended
*
* Note: we choose not to add a new context at each evaluation to save memory
*/
export function startFeatureFlagContexts(
lifeCycle: LifeCycle,
hooks: Hooks,
configuration: RumConfiguration
): FeatureFlagContexts {
const featureFlagContexts = createValueHistory<FeatureFlagContext>({
expireDelay: FEATURE_FLAG_CONTEXT_TIME_OUT_DELAY,
})
lifeCycle.subscribe(LifeCycleEventType.BEFORE_VIEW_CREATED, ({ startClocks }) => {
featureFlagContexts.add({}, startClocks.relative)
})
lifeCycle.subscribe(LifeCycleEventType.AFTER_VIEW_ENDED, ({ endClocks }) => {
featureFlagContexts.closeActive(endClocks.relative)
})
hooks.register(HookNames.Assemble, ({ startTime, eventType }): DefaultRumEventAttributes | SKIPPED => {
const trackFeatureFlagsForEvents = (configuration.trackFeatureFlagsForEvents as RumEventType[]).concat([
RumEventType.VIEW,
RumEventType.VIEW_UPDATE,
RumEventType.ERROR,
])
if (!trackFeatureFlagsForEvents.includes(eventType as RumEventType)) {
return SKIPPED
}
const featureFlagContext = featureFlagContexts.find(startTime)
if (!featureFlagContext || isEmptyObject(featureFlagContext)) {
return SKIPPED
}
return {
type: eventType,
feature_flags: featureFlagContext,
}
})
return {
addFeatureFlagEvaluation: (key: string, value: ContextValue) => {
const currentContext = featureFlagContexts.find()
if (currentContext) {
currentContext[key] = value
}
},
}
}