Gate bitdrift integration (#7088)

* Move Statsig init call earlier

* Gate Bitdrift init call

* Remove IS_TEST env constant

* Mock statsig
This commit is contained in:
dan
2024-12-13 17:14:41 +00:00
committed by GitHub
parent 5655241bef
commit e2a7965e43
12 changed files with 38 additions and 24 deletions
+1 -1
View File
@@ -54,4 +54,4 @@ jobs:
run: yarn intl:build run: yarn intl:build
- name: Run tests - name: Run tests
run: | run: |
NODE_ENV=test EXPO_PUBLIC_ENV=test yarn test --forceExit NODE_ENV=test yarn test --forceExit
+1 -1
View File
@@ -20,7 +20,7 @@ build-web-embed: ## Compile web embed bundle, copy to bskyweb/embedr* directorie
.PHONY: test .PHONY: test
test: ## Run all tests test: ## Run all tests
NODE_ENV=test EXPO_PUBLIC_ENV=test yarn test NODE_ENV=test yarn test
.PHONY: lint .PHONY: lint
lint: ## Run style checks and verify syntax lint: ## Run style checks and verify syntax
+1 -2
View File
@@ -5,9 +5,8 @@ import {LogBox} from 'react-native'
import {registerRootComponent} from 'expo' import {registerRootComponent} from 'expo'
import App from '#/App' import App from '#/App'
import {IS_TEST} from '#/env'
if (IS_TEST) { if (process.env.NODE_ENV === 'test') {
LogBox.ignoreAllLogs() // suppress all logs in tests LogBox.ignoreAllLogs() // suppress all logs in tests
} else { } else {
LogBox.ignoreLogs(['Require cycle:']) // suppress require-cycle warnings, it's fine LogBox.ignoreLogs(['Require cycle:']) // suppress require-cycle warnings, it's fine
+1 -6
View File
@@ -17,11 +17,7 @@ import {useLingui} from '@lingui/react'
import {KeyboardControllerProvider} from '#/lib/hooks/useEnableKeyboardController' import {KeyboardControllerProvider} from '#/lib/hooks/useEnableKeyboardController'
import {QueryProvider} from '#/lib/react-query' import {QueryProvider} from '#/lib/react-query'
import { import {Provider as StatsigProvider, tryFetchGates} from '#/lib/statsig/statsig'
initialize,
Provider as StatsigProvider,
tryFetchGates,
} from '#/lib/statsig/statsig'
import {s} from '#/lib/styles' import {s} from '#/lib/styles'
import {ThemeProvider} from '#/lib/ThemeContext' import {ThemeProvider} from '#/lib/ThemeContext'
import I18nProvider from '#/locale/i18nProvider' import I18nProvider from '#/locale/i18nProvider'
@@ -101,7 +97,6 @@ function InnerApp() {
if (account) { if (account) {
await resumeSession(account) await resumeSession(account)
} else { } else {
await initialize()
await tryFetchGates(undefined, 'prefer-fresh-gates') await tryFetchGates(undefined, 'prefer-fresh-gates')
} }
} catch (e) { } catch (e) {
-1
View File
@@ -1,4 +1,3 @@
export const IS_TEST = process.env.EXPO_PUBLIC_ENV === 'test'
export const IS_DEV = __DEV__ export const IS_DEV = __DEV__
export const IS_PROD = !IS_DEV export const IS_PROD = !IS_DEV
export const LOG_DEBUG = process.env.EXPO_PUBLIC_LOG_DEBUG || '' export const LOG_DEBUG = process.env.EXPO_PUBLIC_LOG_DEBUG || ''
+16 -3
View File
@@ -1,7 +1,20 @@
import {init} from '@bitdrift/react-native' import {init} from '@bitdrift/react-native'
import {Statsig} from 'statsig-react-native-expo'
import {initPromise} from './statsig/statsig'
const BITDRIFT_API_KEY = process.env.BITDRIFT_API_KEY const BITDRIFT_API_KEY = process.env.BITDRIFT_API_KEY
if (BITDRIFT_API_KEY) { initPromise.then(() => {
init(BITDRIFT_API_KEY, {url: 'https://api-bsky.bitdrift.io'}) let isEnabled = false
} try {
if (Statsig.checkGate('enable_bitdrift')) {
isEnabled = true
}
} catch (e) {
// Statsig may complain about it being called too early.
}
if (isEnabled && BITDRIFT_API_KEY) {
init(BITDRIFT_API_KEY, {url: 'https://api-bsky.bitdrift.io'})
}
})
+2 -3
View File
@@ -16,6 +16,8 @@ import {Gate} from './gates'
const SDK_KEY = 'client-SXJakO39w9vIhl3D44u8UupyzFl4oZ2qPIkjwcvuPsV' const SDK_KEY = 'client-SXJakO39w9vIhl3D44u8UupyzFl4oZ2qPIkjwcvuPsV'
export const initPromise = initialize()
type StatsigUser = { type StatsigUser = {
userID: string | undefined userID: string | undefined
// TODO: Remove when enough users have custom.platform: // TODO: Remove when enough users have custom.platform:
@@ -219,9 +221,6 @@ export async function tryFetchGates(
// Use this for less common operations where the user would be OK with a delay. // Use this for less common operations where the user would be OK with a delay.
timeoutMs = 1500 timeoutMs = 1500
} }
// Note: This condition is currently false the very first render because
// Statsig has not initialized yet. In the future, we can fix this by
// doing the initialization ourselves instead of relying on the provider.
if (Statsig.initializeCalled()) { if (Statsig.initializeCalled()) {
await Promise.race([ await Promise.race([
timeout(timeoutMs), timeout(timeoutMs),
+1 -1
View File
@@ -18,7 +18,7 @@ logger.error(error[, metadata])
#### Modes #### Modes
The "modes" referred to here are inferred from the values exported from `#/env`. The "modes" referred to here are inferred from the values exported from `#/env`.
Basically, the booleans `IS_DEV`, `IS_TEST`, and `IS_PROD`. Basically, the booleans `IS_DEV` and `IS_PROD`.
#### Log Levels #### Log Levels
-1
View File
@@ -5,7 +5,6 @@ import {nanoid} from 'nanoid/non-secure'
import {Logger, LogLevel, sentryTransport} from '#/logger' import {Logger, LogLevel, sentryTransport} from '#/logger'
jest.mock('#/env', () => ({ jest.mock('#/env', () => ({
IS_TEST: true,
IS_DEV: false, IS_DEV: false,
IS_PROD: false, IS_PROD: false,
/* /*
+3 -3
View File
@@ -173,7 +173,7 @@ export class Logger {
protected debugContextRegexes: RegExp[] = [] protected debugContextRegexes: RegExp[] = []
constructor({ constructor({
enabled = !env.IS_TEST, enabled = process.env.NODE_ENV !== 'test',
level = env.LOG_LEVEL as LogLevel, level = env.LOG_LEVEL as LogLevel,
debug = env.LOG_DEBUG || '', debug = env.LOG_DEBUG || '',
}: { }: {
@@ -266,11 +266,11 @@ export class Logger {
*/ */
export const logger = new Logger() export const logger = new Logger()
if (!env.IS_TEST) { if (process.env.NODE_ENV !== 'test') {
logger.addTransport(createBitdriftTransport()) logger.addTransport(createBitdriftTransport())
} }
if (env.IS_DEV && !env.IS_TEST) { if (env.IS_DEV && process.env.NODE_ENV !== 'test') {
logger.addTransport(consoleTransport) logger.addTransport(consoleTransport)
/* /*
@@ -4,6 +4,15 @@ import {describe, expect, it, jest} from '@jest/globals'
import {agentToSessionAccountOrThrow} from '../agent' import {agentToSessionAccountOrThrow} from '../agent'
import {Action, getInitialState, reducer, State} from '../reducer' import {Action, getInitialState, reducer, State} from '../reducer'
jest.mock('statsig-react-native-expo', () => ({
Statsig: {
initialize() {},
initializeCalled() {
return false
},
},
}))
jest.mock('jwt-decode', () => ({ jest.mock('jwt-decode', () => ({
jwtDecode(_token: string) { jwtDecode(_token: string) {
return {} return {}
+3 -2
View File
@@ -25,7 +25,6 @@ import {
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
import {atoms as a, useTheme} from '#/alf' import {atoms as a, useTheme} from '#/alf'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
import {IS_TEST} from '#/env'
const TIMEOUT = 2e3 const TIMEOUT = 2e3
@@ -33,7 +32,9 @@ export function show(
message: string, message: string,
icon: FontAwesomeProps['icon'] = 'check', icon: FontAwesomeProps['icon'] = 'check',
) { ) {
if (IS_TEST) return if (process.env.NODE_ENV === 'test') {
return
}
AccessibilityInfo.announceForAccessibility(message) AccessibilityInfo.announceForAccessibility(message)
const item = new RootSiblings( const item = new RootSiblings(
<Toast message={message} icon={icon} destroy={() => item.destroy()} />, <Toast message={message} icon={icon} destroy={() => item.destroy()} />,