Bluesky app fork with some witchin' additions 💫 witchsky.app
bluesky fork

Gate bitdrift integration (#7088)

* Move Statsig init call earlier

* Gate Bitdrift init call

* Remove IS_TEST env constant

* Mock statsig

authored by danabra.mov and committed by GitHub e2a7965e 5655241b

Changed files
+38 -24
.github
workflows
src
lib
logger
state
session
__tests__
view
com
util
+1 -1
.github/workflows/lint.yml
··· 54 54 run: yarn intl:build 55 55 - name: Run tests 56 56 run: | 57 - NODE_ENV=test EXPO_PUBLIC_ENV=test yarn test --forceExit 57 + NODE_ENV=test yarn test --forceExit
+1 -1
Makefile
··· 20 20 21 21 .PHONY: test 22 22 test: ## Run all tests 23 - NODE_ENV=test EXPO_PUBLIC_ENV=test yarn test 23 + NODE_ENV=test yarn test 24 24 25 25 .PHONY: lint 26 26 lint: ## Run style checks and verify syntax
+1 -2
index.js
··· 5 5 import {registerRootComponent} from 'expo' 6 6 7 7 import App from '#/App' 8 - import {IS_TEST} from '#/env' 9 8 10 - if (IS_TEST) { 9 + if (process.env.NODE_ENV === 'test') { 11 10 LogBox.ignoreAllLogs() // suppress all logs in tests 12 11 } else { 13 12 LogBox.ignoreLogs(['Require cycle:']) // suppress require-cycle warnings, it's fine
+1 -6
src/App.native.tsx
··· 17 17 18 18 import {KeyboardControllerProvider} from '#/lib/hooks/useEnableKeyboardController' 19 19 import {QueryProvider} from '#/lib/react-query' 20 - import { 21 - initialize, 22 - Provider as StatsigProvider, 23 - tryFetchGates, 24 - } from '#/lib/statsig/statsig' 20 + import {Provider as StatsigProvider, tryFetchGates} from '#/lib/statsig/statsig' 25 21 import {s} from '#/lib/styles' 26 22 import {ThemeProvider} from '#/lib/ThemeContext' 27 23 import I18nProvider from '#/locale/i18nProvider' ··· 101 97 if (account) { 102 98 await resumeSession(account) 103 99 } else { 104 - await initialize() 105 100 await tryFetchGates(undefined, 'prefer-fresh-gates') 106 101 } 107 102 } catch (e) {
-1
src/env.ts
··· 1 - export const IS_TEST = process.env.EXPO_PUBLIC_ENV === 'test' 2 1 export const IS_DEV = __DEV__ 3 2 export const IS_PROD = !IS_DEV 4 3 export const LOG_DEBUG = process.env.EXPO_PUBLIC_LOG_DEBUG || ''
+16 -3
src/lib/bitdrift.ts
··· 1 1 import {init} from '@bitdrift/react-native' 2 + import {Statsig} from 'statsig-react-native-expo' 3 + 4 + import {initPromise} from './statsig/statsig' 2 5 3 6 const BITDRIFT_API_KEY = process.env.BITDRIFT_API_KEY 4 7 5 - if (BITDRIFT_API_KEY) { 6 - init(BITDRIFT_API_KEY, {url: 'https://api-bsky.bitdrift.io'}) 7 - } 8 + initPromise.then(() => { 9 + let isEnabled = false 10 + try { 11 + if (Statsig.checkGate('enable_bitdrift')) { 12 + isEnabled = true 13 + } 14 + } catch (e) { 15 + // Statsig may complain about it being called too early. 16 + } 17 + if (isEnabled && BITDRIFT_API_KEY) { 18 + init(BITDRIFT_API_KEY, {url: 'https://api-bsky.bitdrift.io'}) 19 + } 20 + })
+2 -3
src/lib/statsig/statsig.tsx
··· 16 16 17 17 const SDK_KEY = 'client-SXJakO39w9vIhl3D44u8UupyzFl4oZ2qPIkjwcvuPsV' 18 18 19 + export const initPromise = initialize() 20 + 19 21 type StatsigUser = { 20 22 userID: string | undefined 21 23 // TODO: Remove when enough users have custom.platform: ··· 219 221 // Use this for less common operations where the user would be OK with a delay. 220 222 timeoutMs = 1500 221 223 } 222 - // Note: This condition is currently false the very first render because 223 - // Statsig has not initialized yet. In the future, we can fix this by 224 - // doing the initialization ourselves instead of relying on the provider. 225 224 if (Statsig.initializeCalled()) { 226 225 await Promise.race([ 227 226 timeout(timeoutMs),
+1 -1
src/logger/README.md
··· 18 18 #### Modes 19 19 20 20 The "modes" referred to here are inferred from the values exported from `#/env`. 21 - Basically, the booleans `IS_DEV`, `IS_TEST`, and `IS_PROD`. 21 + Basically, the booleans `IS_DEV` and `IS_PROD`. 22 22 23 23 #### Log Levels 24 24
-1
src/logger/__tests__/logger.test.ts
··· 5 5 import {Logger, LogLevel, sentryTransport} from '#/logger' 6 6 7 7 jest.mock('#/env', () => ({ 8 - IS_TEST: true, 9 8 IS_DEV: false, 10 9 IS_PROD: false, 11 10 /*
+3 -3
src/logger/index.ts
··· 173 173 protected debugContextRegexes: RegExp[] = [] 174 174 175 175 constructor({ 176 - enabled = !env.IS_TEST, 176 + enabled = process.env.NODE_ENV !== 'test', 177 177 level = env.LOG_LEVEL as LogLevel, 178 178 debug = env.LOG_DEBUG || '', 179 179 }: { ··· 266 266 */ 267 267 export const logger = new Logger() 268 268 269 - if (!env.IS_TEST) { 269 + if (process.env.NODE_ENV !== 'test') { 270 270 logger.addTransport(createBitdriftTransport()) 271 271 } 272 272 273 - if (env.IS_DEV && !env.IS_TEST) { 273 + if (env.IS_DEV && process.env.NODE_ENV !== 'test') { 274 274 logger.addTransport(consoleTransport) 275 275 276 276 /*
+9
src/state/session/__tests__/session-test.ts
··· 4 4 import {agentToSessionAccountOrThrow} from '../agent' 5 5 import {Action, getInitialState, reducer, State} from '../reducer' 6 6 7 + jest.mock('statsig-react-native-expo', () => ({ 8 + Statsig: { 9 + initialize() {}, 10 + initializeCalled() { 11 + return false 12 + }, 13 + }, 14 + })) 15 + 7 16 jest.mock('jwt-decode', () => ({ 8 17 jwtDecode(_token: string) { 9 18 return {}
+3 -2
src/view/com/util/Toast.tsx
··· 25 25 import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' 26 26 import {atoms as a, useTheme} from '#/alf' 27 27 import {Text} from '#/components/Typography' 28 - import {IS_TEST} from '#/env' 29 28 30 29 const TIMEOUT = 2e3 31 30 ··· 33 32 message: string, 34 33 icon: FontAwesomeProps['icon'] = 'check', 35 34 ) { 36 - if (IS_TEST) return 35 + if (process.env.NODE_ENV === 'test') { 36 + return 37 + } 37 38 AccessibilityInfo.announceForAccessibility(message) 38 39 const item = new RootSiblings( 39 40 <Toast message={message} icon={icon} destroy={() => item.destroy()} />,