···11import React from 'react'
22-import {Platform} from 'react-native'
33-import {AppState, type AppStateStatus} from 'react-native'
44-import {Statsig, StatsigProvider} from 'statsig-react-native-expo'
22+import {AppState, type AppStateStatus, Platform} from 'react-native'
33+import {Statsig} from 'statsig-react-native-expo'
5465import {logger} from '#/logger'
76import {type MetricEvents} from '#/logger/metrics'
87import {isWeb} from '#/platform/detection'
98import * as persisted from '#/state/persisted'
109import * as env from '#/env'
1111-import {useSession} from '../../state/session'
1210import {timeout} from '../async/timeout'
1313-import {useNonReactiveCallback} from '../hooks/useNonReactiveCallback'
1411import {type Gate} from './gates'
1515-1616-const SDK_KEY = 'client-SXJakO39w9vIhl3D44u8UupyzFl4oZ2qPIkjwcvuPsV'
17121813export const initPromise = initialize()
1914···4439}
45404641export type {MetricEvents as LogEvents}
4747-4848-function createStatsigOptions(prefetchUsers: StatsigUser[]) {
4949- return {
5050- environment: {
5151- tier: env.IS_DEV
5252- ? 'development'
5353- : env.IS_TESTFLIGHT
5454- ? 'staging'
5555- : 'production',
5656- },
5757- // Don't block on waiting for network. The fetched config will kick in on next load.
5858- // This ensures the UI is always consistent and doesn't update mid-session.
5959- // Note this makes cold load (no local storage) and private mode return `false` for all gates.
6060- initTimeoutMs: 1,
6161- // Get fresh flags for other accounts as well, if any.
6262- prefetchUsers,
6363- api: 'https://events.bsky.app/v2',
6464- }
6565-}
66426743type FlatJSONRecord = Record<
6844 string,
···265241}
266242267243export function initialize() {
268268- return Statsig.initialize(SDK_KEY, null, createStatsigOptions([]))
244244+ return new Promise(() => {})
269245}
270246271247export function Provider({children}: {children: React.ReactNode}) {
272272- const {currentAccount, accounts} = useSession()
273273- const did = currentAccount?.did
274274- const currentStatsigUser = React.useMemo(() => toStatsigUser(did), [did])
275275-276276- const otherDidsConcatenated = accounts
277277- .map(account => account.did)
278278- .filter(accountDid => accountDid !== did)
279279- .join(' ') // We're only interested in DID changes.
280280- const otherStatsigUsers = React.useMemo(
281281- () => otherDidsConcatenated.split(' ').map(toStatsigUser),
282282- [otherDidsConcatenated],
283283- )
284284- const statsigOptions = React.useMemo(
285285- () => createStatsigOptions(otherStatsigUsers),
286286- [otherStatsigUsers],
287287- )
288288-289289- // Have our own cache in front of Statsig.
290290- // This ensures the results remain stable until the active DID changes.
291291- const [gateCache, setGateCache] = React.useState(() => new Map())
292292- const [prevDid, setPrevDid] = React.useState(did)
293293- if (did !== prevDid) {
294294- setPrevDid(did)
295295- setGateCache(new Map())
296296- }
297297-298298- // Periodically poll Statsig to get the current rule evaluations for all stored accounts.
299299- // These changes are prefetched and stored, but don't get applied until the active DID changes.
300300- // This ensures that when you switch an account, it already has fresh results by then.
301301- const handleIntervalTick = useNonReactiveCallback(() => {
302302- if (Statsig.initializeCalled()) {
303303- // Note: Only first five will be taken into account by Statsig.
304304- Statsig.prefetchUsers([currentStatsigUser, ...otherStatsigUsers])
305305- }
306306- })
307307- React.useEffect(() => {
308308- const id = setInterval(handleIntervalTick, 60e3 /* 1 min */)
309309- return () => clearInterval(id)
310310- }, [handleIntervalTick])
311311-312312- return (
313313- <GateCache.Provider value={gateCache}>
314314- <StatsigProvider
315315- key={did}
316316- sdkKey={SDK_KEY}
317317- mountKey={currentStatsigUser.userID}
318318- user={currentStatsigUser}
319319- // This isn't really blocking due to short initTimeoutMs above.
320320- // However, it ensures `isLoading` is always `false`.
321321- waitForInitialization={true}
322322- options={statsigOptions}>
323323- {children}
324324- </StatsigProvider>
325325- </GateCache.Provider>
326326- )
248248+ const [gateCache] = React.useState(() => new Map())
249249+ return <GateCache.Provider value={gateCache}>{children}</GateCache.Provider>
327250}
+3-6
src/logger/index.ts
···33import {logEvent} from '#/lib/statsig/statsig'
44import {add} from '#/logger/logDump'
55import {type MetricEvents} from '#/logger/metrics'
66-import {bitdriftTransport} from '#/logger/transports/bitdrift'
76import {consoleTransport} from '#/logger/transports/console'
88-import {sentryTransport} from '#/logger/transports/sentry'
97import {
108 LogContext,
119 LogLevel,
···1311 type Transport,
1412} from '#/logger/types'
1513import {enabledLogLevels} from '#/logger/util'
1616-import {isNative} from '#/platform/detection'
1714import {ENV} from '#/env'
18151916const TRANSPORTS: Transport[] = (function configureTransports() {
2017 switch (ENV) {
2118 case 'production': {
2222- return [sentryTransport, isNative && bitdriftTransport].filter(
2323- Boolean,
2424- ) as Transport[]
1919+ // return [sentryTransport, isNative && bitdriftTransport].filter(
2020+ // Boolean,
2121+ // ) as Transport[]
2522 }
2623 case 'test': {
2724 return []