Skip to content

Commit 0f32cb5

Browse files
committed
ref(flags): Refactor LaunchDarkly integration to reusable functions
Moves core logic into re-usable functions so that we can re-use for other integrations.
1 parent 7b3382f commit 0f32cb5

File tree

2 files changed

+33
-28
lines changed

2 files changed

+33
-28
lines changed

packages/browser/src/integrations/featureFlags/launchdarkly/integration.ts

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import type { Client, Event, EventHint, IntegrationFn } from '@sentry/types';
22
import type { LDContext, LDEvaluationDetail, LDInspectionFlagUsedHandler } from './types';
33

4-
import { defineIntegration, getCurrentScope } from '@sentry/core';
5-
import { insertToFlagBuffer } from '../../../utils/featureFlags';
4+
import { defineIntegration } from '@sentry/core';
5+
import { copyFlagsFromScopeToEvent, insertToFlagBuffer } from '../../../utils/featureFlags';
66

77
/**
88
* Sentry integration for capturing feature flags from LaunchDarkly.
@@ -24,15 +24,7 @@ export const launchDarklyIntegration = defineIntegration(() => {
2424
name: 'LaunchDarkly',
2525

2626
processEvent(event: Event, _hint: EventHint, _client: Client): Event {
27-
const scope = getCurrentScope();
28-
const flagContext = scope.getScopeData().contexts.flags;
29-
const flagBuffer = flagContext ? flagContext.values : [];
30-
31-
if (event.contexts === undefined) {
32-
event.contexts = {};
33-
}
34-
event.contexts.flags = { values: [...flagBuffer] };
35-
return event;
27+
return copyFlagsFromScopeToEvent(event);
3628
},
3729
};
3830
}) satisfies IntegrationFn;
@@ -54,15 +46,7 @@ export function buildLaunchDarklyFlagUsedHandler(): LDInspectionFlagUsedHandler
5446
* Handle a flag evaluation by storing its name and value on the current scope.
5547
*/
5648
method: (flagKey: string, flagDetail: LDEvaluationDetail, _context: LDContext) => {
57-
if (typeof flagDetail.value === 'boolean') {
58-
const scopeContexts = getCurrentScope().getScopeData().contexts;
59-
if (!scopeContexts.flags) {
60-
scopeContexts.flags = { values: [] };
61-
}
62-
const flagBuffer = scopeContexts.flags.values;
63-
insertToFlagBuffer(flagBuffer, flagKey, flagDetail.value);
64-
}
65-
return;
49+
insertToFlagBuffer(flagKey, flagDetail.value);
6650
},
6751
};
6852
}

packages/browser/src/utils/featureFlags.ts

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import type { FeatureFlag } from '@sentry/types';
1+
import { getCurrentScope } from '@sentry/core';
2+
import type { Event, FeatureFlag } from '@sentry/types';
23
import { logger } from '@sentry/utils';
34
import { DEBUG_BUILD } from '../debug-build';
45

@@ -13,6 +14,21 @@ import { DEBUG_BUILD } from '../debug-build';
1314
*/
1415
export const FLAG_BUFFER_SIZE = 100;
1516

17+
/**
18+
* Copies feature flags that are in current scope context to the event context
19+
*/
20+
export function copyFlagsFromScopeToEvent(event: Event): Event {
21+
const scope = getCurrentScope();
22+
const flagContext = scope.getScopeData().contexts.flags;
23+
const flagBuffer = flagContext ? flagContext.values : [];
24+
25+
if (event.contexts === undefined) {
26+
event.contexts = {};
27+
}
28+
event.contexts.flags = { values: [...flagBuffer] };
29+
return event;
30+
}
31+
1632
/**
1733
* Insert into a FeatureFlag array while maintaining ordered LRU properties. Not
1834
* thread-safe. After inserting:
@@ -21,18 +37,23 @@ export const FLAG_BUFFER_SIZE = 100;
2137
* - The length of `flags` does not exceed `maxSize`. The oldest flag is evicted
2238
* as needed.
2339
*
24-
* @param flags The array to insert into.
2540
* @param name Name of the feature flag to insert.
2641
* @param value Value of the feature flag.
2742
* @param maxSize Max number of flags the buffer should store. It's recommended
2843
* to keep this consistent across insertions. Default is DEFAULT_MAX_SIZE
2944
*/
30-
export function insertToFlagBuffer(
31-
flags: FeatureFlag[],
32-
name: string,
33-
value: boolean,
34-
maxSize: number = FLAG_BUFFER_SIZE,
35-
): void {
45+
export function insertToFlagBuffer(name: string, value: unknown, maxSize: number = FLAG_BUFFER_SIZE): void {
46+
// Currently only accepts boolean values
47+
if (typeof value !== 'boolean') {
48+
return;
49+
}
50+
51+
const scopeContexts = getCurrentScope().getScopeData().contexts;
52+
if (!scopeContexts.flags) {
53+
scopeContexts.flags = { values: [] };
54+
}
55+
const flags = scopeContexts.flags.values as FeatureFlag[];
56+
3657
if (flags.length > maxSize) {
3758
DEBUG_BUILD && logger.error(`[Feature Flags] insertToFlagBuffer called on a buffer larger than maxSize=${maxSize}`);
3859
return;

0 commit comments

Comments
 (0)