Skip to content

Commit a42091f

Browse files
committed
refactor(expo): address PR review feedback
- Extract repeated native module init pattern into shared utils/native-module.ts - Add __DEV__ console.warn to all empty catch blocks for observability - Use unique ClerkRuntimeError codes for AuthView and InlineAuthView throws - Lift getInitials() out of UserButton component to module scope - Add __DEV__ logging to token cache and expo-web-browser catches in ClerkProvider - Delete slop README.md from native directory
1 parent c59b281 commit a42091f

12 files changed

Lines changed: 81 additions & 396 deletions

packages/expo/src/hooks/useNativeAuthEvents.ts

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,7 @@
11
import { useEffect, useState } from 'react';
2-
import { NativeEventEmitter, Platform } from 'react-native';
2+
import { NativeEventEmitter } from 'react-native';
33

4-
import NativeClerkModule from '../specs/NativeClerkModule';
5-
6-
// Check if native module is supported on this platform
7-
const isNativeSupported = Platform.OS === 'ios' || Platform.OS === 'android';
8-
9-
// Get the native module for event listening
10-
let ClerkExpo: typeof NativeClerkModule | null = null;
11-
12-
if (isNativeSupported) {
13-
try {
14-
ClerkExpo = NativeClerkModule;
15-
} catch {
16-
// Native module not available - plugin not configured
17-
ClerkExpo = null;
18-
}
19-
}
4+
import { ClerkExpoModule as ClerkExpo, isNativeSupported } from '../utils/native-module';
205

216
/**
227
* Auth state change event from native SDK

packages/expo/src/hooks/useNativeSession.ts

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
import { useCallback, useEffect, useState } from 'react';
2-
import { Platform } from 'react-native';
32

4-
import NativeClerkModule from '../specs/NativeClerkModule';
5-
6-
// Check if native module is supported on this platform
7-
const isNativeSupported = Platform.OS === 'ios' || Platform.OS === 'android';
3+
import { ClerkExpoModule as ClerkExpo, isNativeSupported } from '../utils/native-module';
84

95
// Native session data structure (normalized)
106
interface NativeSessionData {
@@ -25,17 +21,6 @@ interface NativeSessionRawResult {
2521
user?: NativeSessionData['user'];
2622
}
2723

28-
// Safely get the native module
29-
let ClerkExpo: typeof NativeClerkModule | null = null;
30-
31-
if (isNativeSupported) {
32-
try {
33-
ClerkExpo = NativeClerkModule;
34-
} catch {
35-
// Native module not available - this is expected when expo plugin is not installed
36-
}
37-
}
38-
3924
export interface UseNativeSessionReturn {
4025
/**
4126
* Whether the native module is available (expo plugin installed)

packages/expo/src/hooks/useUserProfileModal.ts

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,14 @@
11
import { useClerk } from '@clerk/react';
22
import { useCallback, useRef } from 'react';
3-
import { Platform } from 'react-native';
43

5-
import NativeClerkModule from '../specs/NativeClerkModule';
6-
7-
// Check if native module is supported on this platform
8-
const isNativeSupported = Platform.OS === 'ios' || Platform.OS === 'android';
4+
import { ClerkExpoModule as ClerkExpo, isNativeSupported } from '../utils/native-module';
95

106
// Raw result from the native module (may vary by platform)
117
type NativeSessionResult = {
128
sessionId?: string;
139
session?: { id: string };
1410
};
1511

16-
// Safely get the native module
17-
let ClerkExpo: typeof NativeClerkModule | null = null;
18-
if (isNativeSupported) {
19-
try {
20-
ClerkExpo = NativeClerkModule;
21-
} catch {
22-
ClerkExpo = null;
23-
}
24-
}
25-
2612
export interface UseUserProfileModalReturn {
2713
/**
2814
* Present the native user profile modal.
@@ -93,16 +79,20 @@ export function useUserProfileModal(): UseUserProfileModalReturn {
9379
// Clear native session explicitly (may already be cleared, but ensure it)
9480
try {
9581
await ClerkExpo.signOut?.();
96-
} catch {
97-
// May already be signed out
82+
} catch (e) {
83+
if (__DEV__) {
84+
console.warn('[useUserProfileModal] Native signOut error (may already be signed out):', e);
85+
}
9886
}
9987

10088
// Sign out from JS SDK to update isSignedIn state
10189
if (clerk?.signOut) {
10290
try {
10391
await clerk.signOut();
104-
} catch {
105-
// Best effort
92+
} catch (e) {
93+
if (__DEV__) {
94+
console.warn('[useUserProfileModal] Best-effort JS SDK signOut failed:', e);
95+
}
10696
}
10797
}
10898
}

packages/expo/src/native/AuthView.tsx

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,14 @@
11
import { ClerkRuntimeError } from '@clerk/shared/error';
22
import { useCallback, useRef } from 'react';
3-
import { Platform, Text, View } from 'react-native';
3+
import { Text, View } from 'react-native';
44

55
import { CLERK_CLIENT_JWT_KEY } from '../constants';
66
import { getClerkInstance } from '../provider/singleton';
77
import NativeClerkAuthView from '../specs/NativeClerkAuthView';
8-
import NativeClerkModule from '../specs/NativeClerkModule';
98
import { tokenCache } from '../token-cache';
9+
import { ClerkExpoModule as ClerkExpo, isNativeSupported } from '../utils/native-module';
1010
import type { AuthViewProps } from './AuthView.types';
1111

12-
// Check if native module is supported on this platform
13-
const isNativeSupported = Platform.OS === 'ios' || Platform.OS === 'android';
14-
15-
// Safely get the native module
16-
let ClerkExpo: typeof NativeClerkModule | null = null;
17-
if (isNativeSupported) {
18-
try {
19-
ClerkExpo = NativeClerkModule;
20-
} catch {
21-
ClerkExpo = null;
22-
}
23-
}
24-
2512
export async function syncNativeSession(sessionId: string): Promise<void> {
2613
// Copy the native client's bearer token to the JS SDK's token cache
2714
if (ClerkExpo?.getClientToken) {
@@ -41,7 +28,7 @@ export async function syncNativeSession(sessionId: string): Promise<void> {
4128
if (!clerkInstance) {
4229
throw new ClerkRuntimeError(
4330
'Clerk instance is not available. Ensure <ClerkProvider> is mounted before using <AuthView>.',
44-
{ code: 'clerk_instance_not_available' },
31+
{ code: 'expo_auth_view_clerk_instance_not_available' },
4532
);
4633
}
4734

packages/expo/src/native/InlineAuthView.tsx

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,14 @@
11
import { ClerkRuntimeError } from '@clerk/shared/error';
22
import { useCallback, useRef } from 'react';
3-
import { Platform, StyleSheet, Text, View } from 'react-native';
3+
import { StyleSheet, Text, View } from 'react-native';
44

55
import { CLERK_CLIENT_JWT_KEY } from '../constants';
66
import { getClerkInstance } from '../provider/singleton';
77
import NativeClerkAuthView from '../specs/NativeClerkAuthView';
8-
import NativeClerkModule from '../specs/NativeClerkModule';
98
import { tokenCache } from '../token-cache';
9+
import { ClerkExpoModule, isNativeSupported } from '../utils/native-module';
1010
import type { AuthViewMode } from './AuthView.types';
1111

12-
// Check if native module is supported on this platform
13-
const isNativeSupported = Platform.OS === 'ios' || Platform.OS === 'android';
14-
15-
// Safely get the native module
16-
let ClerkExpoModule: typeof NativeClerkModule | null = null;
17-
if (isNativeSupported) {
18-
try {
19-
ClerkExpoModule = NativeClerkModule;
20-
} catch {
21-
ClerkExpoModule = null;
22-
}
23-
}
24-
2512
export interface InlineAuthViewProps {
2613
/**
2714
* Authentication mode that determines which flows are available.
@@ -86,7 +73,7 @@ export function InlineAuthView({ mode = 'signInOrUp', isDismissable = false }: I
8673
if (!clerkInstance) {
8774
throw new ClerkRuntimeError(
8875
'Clerk instance is not available. Ensure <ClerkProvider> is mounted before using <InlineAuthView>.',
89-
{ code: 'clerk_instance_not_available' },
76+
{ code: 'expo_inline_auth_view_clerk_instance_not_available' },
9077
);
9178
}
9279

packages/expo/src/native/InlineUserProfileView.tsx

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,9 @@
11
import { useClerk } from '@clerk/react';
22
import { useCallback, useRef } from 'react';
3-
import { Platform, type StyleProp, StyleSheet, Text, View, type ViewStyle } from 'react-native';
3+
import { type StyleProp, StyleSheet, Text, View, type ViewStyle } from 'react-native';
44

5-
import NativeClerkModule from '../specs/NativeClerkModule';
65
import NativeClerkUserProfileView from '../specs/NativeClerkUserProfileView';
7-
8-
// Check if native module is supported on this platform
9-
const isNativeSupported = Platform.OS === 'ios' || Platform.OS === 'android';
10-
11-
// Safely get the native module
12-
let ClerkExpo: typeof NativeClerkModule | null = null;
13-
if (isNativeSupported) {
14-
try {
15-
ClerkExpo = NativeClerkModule;
16-
} catch {
17-
ClerkExpo = null;
18-
}
19-
}
6+
import { ClerkExpoModule as ClerkExpo, isNativeSupported } from '../utils/native-module';
207

218
export interface InlineUserProfileViewProps {
229
/**
@@ -69,8 +56,10 @@ export function InlineUserProfileView({ isDismissable = false, style }: InlineUs
6956
// Clear native session
7057
try {
7158
await ClerkExpo?.signOut();
72-
} catch {
73-
// May already be signed out
59+
} catch (e) {
60+
if (__DEV__) {
61+
console.warn('[InlineUserProfileView] Native signOut error (may already be signed out):', e);
62+
}
7463
}
7564

7665
// Sign out from JS SDK

0 commit comments

Comments
 (0)