-
Notifications
You must be signed in to change notification settings - Fork 16
/
useFeatureFlag.tsx
101 lines (88 loc) · 2.31 KB
/
useFeatureFlag.tsx
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// TODO(2fd): add Docs
import { useCallback, useMemo } from 'react'
import {
FeatureFlagOptions,
FeatureFlagsResult,
fetchFlags,
} from '@dcl/feature-flags'
import FeatureFlags from '../utils/development/FeatureFlags'
import useAsyncState from './useAsyncState'
export const DEFAULT_FEATURE_FLAG = new FeatureFlags({
flags: {},
variants: {},
})
export type { FeatureFlagOptions, FeatureFlagsResult }
export default function useFeatureFlag(options: Partial<FeatureFlagOptions>) {
const [ff, asyncState] = useAsyncState(
async () => {
if (!options.applicationName) {
return DEFAULT_FEATURE_FLAG
}
const ff = await fetchFlags(options as FeatureFlagOptions)
return new FeatureFlags(ff)
},
[
options.applicationName,
options.debug,
options.featureFlagsUrl,
options.userId,
],
{
initialValue: DEFAULT_FEATURE_FLAG,
}
)
const isEnabled = useCallback(
/** @deprecated use ff.enabled(KEY) instead */
(key: string) => {
return (
!!ff &&
!!options.applicationName &&
!!ff.flags[`${options.applicationName}-${key}`]
)
},
[ff]
)
const getVariantName = useCallback(
/** @deprecated use ff.name(KEY) instead */
<K extends string = string, D = null>(
key: string,
defaultVariant: D
): K | D => {
if (isEnabled(key)) {
const variant = ff.variants[`${options.applicationName}-${key}`]
if (variant.payload?.value) {
return variant.payload.value as K
}
}
return defaultVariant ?? (null as any)
},
[ff]
)
const getVariantValue = useCallback(
/** @deprecated use ff.payload(KEY) instead */
<K extends string = string, D = null>(
key: string,
defaultVariant: D
): K | D => {
if (isEnabled(key)) {
const variant = ff.variants[`${options.applicationName}-${key}`]
if (variant.payload?.value) {
return variant.payload.value as K
}
}
return defaultVariant ?? (null as any)
},
[ff]
)
const state = useMemo(
() => ({
...asyncState,
isEnabled,
getVariant: getVariantValue,
getVariantValue,
getVariantName,
}),
[asyncState, isEnabled, getVariantName, getVariantValue]
)
return [ff, state] as const
}