Skip to content

Commit 2b79c63

Browse files
committed
feat!: replace undefined installSource with explicit "sideloaded" enum value
1 parent b7ca2fb commit 2b79c63

24 files changed

+83
-80
lines changed

bun.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/docs/api-reference.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { VersionCheck } from 'react-native-nitro-version-check'
2020
| `version` | `string` | App version (`CFBundleShortVersionString` on iOS, `versionName` on Android) |
2121
| `buildNumber` | `string` | Build number (`CFBundleVersion` on iOS, `versionCode` on Android) |
2222
| `packageName` | `string` | Bundle ID (iOS) / Application ID (Android) |
23-
| `installSource` | `string \| undefined` | `"appstore"`, `"testflight"`, `"playstore"`, or `undefined` for dev/sideloaded builds |
23+
| `installSource` | `string` | `"appstore"`, `"testflight"`, `"playstore"`, or `"sideloaded"`. On iOS, `"sideloaded"` indicates a dev build. On Android, it means the app was installed via APK/ADB (dev or release). |
2424

2525
### Methods
2626

docs/docs/getting-started.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import { VersionCheck } from 'react-native-nitro-version-check'
4040
console.log(VersionCheck.version) // "1.2.0"
4141
console.log(VersionCheck.buildNumber) // "42"
4242
console.log(VersionCheck.packageName) // "com.example.app"
43-
console.log(VersionCheck.installSource) // "appstore" | "testflight" | "playstore" | undefined
43+
console.log(VersionCheck.installSource) // "appstore" | "testflight" | "playstore" | "sideloaded"
4444
console.log(VersionCheck.getCountry()) // "US"
4545

4646
// Or destructure properties

docs/docs/usage-examples.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const info = {
1717
version: VersionCheck.version, // "1.2.0"
1818
build: VersionCheck.buildNumber, // "42"
1919
package: VersionCheck.packageName, // "com.example.app"
20-
source: VersionCheck.installSource, // "appstore" | undefined
20+
source: VersionCheck.installSource, // "appstore" | "sideloaded"
2121
country: VersionCheck.getCountry(), // "US"
2222
}
2323

@@ -89,8 +89,11 @@ switch (VersionCheck.installSource) {
8989
case 'playstore':
9090
console.log('Running Play Store build')
9191
break
92-
default:
93-
console.log('Development or sideloaded build')
92+
case 'sideloaded':
93+
// iOS: dev build (e.g. Xcode)
94+
// Android: installed via APK/ADB (dev or release)
95+
console.log('Sideloaded build')
96+
break
9497
}
9598
```
9699

example/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export default function App() {
5151
<Text style={styles.label}>Build: {VersionCheck.buildNumber}</Text>
5252
<Text style={styles.label}>Package: {VersionCheck.packageName}</Text>
5353
<Text style={styles.label}>Country: {VersionCheck.getCountry()}</Text>
54-
<Text style={styles.label}>Install: {VersionCheck.installSource ?? "Dev Build"}</Text>
54+
<Text style={styles.label}>Install: {VersionCheck.installSource}</Text>
5555

5656
<View style={styles.divider} />
5757

example/BenchmarkScreen.tsx

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useCallback, useState } from "react";
2-
import { ActivityIndicator, Platform, ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native";
2+
import { Platform, ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native";
33
import { VersionCheck as NitroVC } from "react-native-nitro-version-check";
44
import RNVersionCheck from "react-native-version-check";
55

@@ -10,7 +10,7 @@ type BenchmarkResult = {
1010
id: string;
1111
name: string;
1212
nitroMs: number;
13-
bridgeMs: number;
13+
bridgeMs: number | null;
1414
note?: string;
1515
section?: string;
1616
};
@@ -44,6 +44,9 @@ export default function BenchmarkScreen({ onBack }: { onBack: () => void }) {
4444
setRunning(true);
4545
setResults([]);
4646

47+
// Yield to let React render the "Running..." state before blocking the thread
48+
await new Promise(resolve => requestAnimationFrame(resolve));
49+
4750
const benchmarks: BenchmarkResult[] = [];
4851
const iter = ITERATIONS.toLocaleString();
4952

@@ -63,6 +66,7 @@ export default function BenchmarkScreen({ onBack }: { onBack: () => void }) {
6366
nitro.packageName;
6467
nitro.version;
6568
nitro.buildNumber;
69+
nitro.installSource;
6670
nitro.getCountry();
6771
bridge.getPackageName();
6872
bridge.getCurrentVersion();
@@ -78,6 +82,7 @@ export default function BenchmarkScreen({ onBack }: { onBack: () => void }) {
7882
nitro.packageName;
7983
nitro.version;
8084
nitro.buildNumber;
85+
nitro.installSource;
8186
nitro.getCountry();
8287
}
8388
nitroAllTotal += performance.now() - ns;
@@ -97,7 +102,7 @@ export default function BenchmarkScreen({ onBack }: { onBack: () => void }) {
97102
name: `getAllInfo (${iter}x)`,
98103
nitroMs: nitroAllTotal / RUNS,
99104
bridgeMs: bridgeAllTotal / RUNS,
100-
note: `pkg + version + build + country (avg of ${RUNS} runs)`,
105+
note: `pkg + version + build + installSource + country (avg of ${RUNS} runs)`,
101106
section: "Real-world Usage",
102107
});
103108

@@ -132,6 +137,14 @@ export default function BenchmarkScreen({ onBack }: { onBack: () => void }) {
132137
note: `Nitro: property | Bridge: fn call (avg of ${RUNS} runs)`,
133138
});
134139

140+
benchmarks.push({
141+
id: "install-source",
142+
name: `installSource (${iter}x)`,
143+
nitroMs: averageSync(() => nitro.installSource, ITERATIONS, RUNS),
144+
bridgeMs: null,
145+
note: `Nitro: property | Bridge: not supported (avg of ${RUNS} runs)`,
146+
});
147+
135148
// getCountry — average over RUNS
136149
const nitroCountry = averageSync(() => nitro.getCountry(), ITERATIONS, RUNS);
137150
let bridgeCountryTotal = 0;
@@ -165,15 +178,15 @@ export default function BenchmarkScreen({ onBack }: { onBack: () => void }) {
165178
<View style={{ width: 40 }} />
166179
</View>
167180

168-
<Text style={styles.subtitle}>Nitro (JSI) vs react-native-version-check (Bridge) — up to 3.7x faster</Text>
181+
<Text style={styles.subtitle}>Nitro (JSI) vs react-native-version-check (Bridge) </Text>
169182

170183
<TouchableOpacity
171184
style={[styles.runButton, running && styles.runButtonDisabled]}
172185
onPress={runBenchmark}
173186
disabled={running}
174187
>
175188
{running ? (
176-
<ActivityIndicator color="#fff" size="small" />
189+
<Text style={styles.runButtonText}>Running...</Text>
177190
) : (
178191
<Text style={styles.runButtonText}>Run Benchmark</Text>
179192
)}
@@ -188,7 +201,7 @@ export default function BenchmarkScreen({ onBack }: { onBack: () => void }) {
188201
</View>
189202

190203
{results.map(r => {
191-
const speedup = r.bridgeMs > 0 && r.nitroMs > 0 ? r.bridgeMs / r.nitroMs : null;
204+
const speedup = r.bridgeMs != null && r.bridgeMs > 0 && r.nitroMs > 0 ? r.bridgeMs / r.nitroMs : null;
192205

193206
return (
194207
<View key={r.id}>
@@ -200,17 +213,17 @@ export default function BenchmarkScreen({ onBack }: { onBack: () => void }) {
200213
<Text style={[styles.cell, styles.cellValue]}>
201214
{r.nitroMs < 0 ? "err" : `${r.nitroMs.toFixed(1)}ms`}
202215
</Text>
203-
<Text style={[styles.cell, styles.cellValue]}>
204-
{r.bridgeMs < 0 ? "err" : `${r.bridgeMs.toFixed(1)}ms`}
216+
<Text style={[styles.cell, styles.cellValue, r.bridgeMs == null && styles.naText]}>
217+
{r.bridgeMs == null ? "N/A" : r.bridgeMs < 0 ? "err" : `${r.bridgeMs.toFixed(1)}ms`}
205218
</Text>
206219
<Text
207220
style={[
208221
styles.cell,
209222
styles.cellSpeed,
210-
speedup != null && speedup > 1 ? styles.faster : styles.slower,
223+
speedup != null && speedup > 1 ? styles.faster : speedup != null ? styles.slower : styles.naText,
211224
]}
212225
>
213-
{speedup != null ? `${speedup.toFixed(1)}x` : "-"}
226+
{speedup != null ? `${speedup.toFixed(1)}x` : r.bridgeMs == null ? "N/A" : "-"}
214227
</Text>
215228
</View>
216229
{r.note && <Text style={styles.note}>{r.note}</Text>}
@@ -330,6 +343,10 @@ const styles = StyleSheet.create({
330343
slower: {
331344
color: "#FF3B30",
332345
},
346+
naText: {
347+
color: "#ccc",
348+
fontStyle: "italic",
349+
},
333350
note: {
334351
fontSize: 11,
335352
color: "#aaa",

package/android/src/main/java/com/margelo/nitro/nitroversioncheck/HybridVersionCheck.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ class HybridVersionCheck : HybridVersionCheckSpec() {
3030

3131
public override val packageName = packageInfo?.packageName
3232
?: error("[VersionCheck] Failed to read 'packageName' from PackageInfo")
33-
public override val installSource: InstallSource? = run {
33+
public override val installSource: InstallSource = run {
3434
val installer = if (android.os.Build.VERSION.SDK_INT >= 30) {
3535
context?.packageManager?.getInstallSourceInfo(context.packageName)?.installingPackageName
3636
} else {
3737
@Suppress("DEPRECATION")
3838
context?.packageManager?.getInstallerPackageName(context.packageName)
3939
}
40-
if (installer != null) InstallSource.PLAYSTORE else null
40+
if (installer != null) InstallSource.PLAYSTORE else InstallSource.SIDELOADED
4141
}
4242

4343
override fun getCountry(): String {

package/ios/HybridVersionCheck.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ class HybridVersionCheck: HybridVersionCheckSpec {
1515
?? { fatalError("[VersionCheck] Failed to read 'buildNumber' (CFBundleVersion) from Info.plist") }()
1616
var packageName = Bundle.main.infoDictionary?["CFBundleIdentifier"] as? String
1717
?? { fatalError("[VersionCheck] Failed to read 'packageName' (CFBundleIdentifier) from Info.plist") }()
18-
var installSource: InstallSource? = {
18+
var installSource: InstallSource = {
1919
guard let receiptURL = Bundle.main.appStoreReceiptURL,
2020
FileManager.default.fileExists(atPath: receiptURL.path) else {
21-
return nil
21+
return .sideloaded
2222
}
2323
if receiptURL.lastPathComponent == "sandboxReceipt" {
2424
return .testflight

package/nitrogen/generated/android/c++/JHybridVersionCheckSpec.cpp

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package/nitrogen/generated/android/c++/JHybridVersionCheckSpec.hpp

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)