Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"packages/sdk/react/examples/vercel-edge",
"packages/sdk/react-native",
"packages/sdk/react-native/example",
"packages/sdk/react-native/example-fdv2",
"packages/sdk/react-native/contract-tests/entity",
"packages/sdk/vercel",
"packages/sdk/svelte",
Expand Down
1 change: 1 addition & 0 deletions packages/sdk/react-native/example-fdv2/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MOBILE_KEY=
Comment thread
kinyoklion marked this conversation as resolved.
Outdated
44 changes: 44 additions & 0 deletions packages/sdk/react-native/example-fdv2/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files
.env

# dependencies
node_modules/

# Expo
.expo/
dist/
web-build/

# Native
*.orig.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision

# Metro
.metro-health-check*

# debug
npm-debug.*
yarn-debug.*
yarn-error.*

# macOS
.DS_Store
*.pem

# local env files
.env*.local

# typescript
*.tsbuildinfo

ios
android

!yarn.lock

# detox
artifacts
27 changes: 27 additions & 0 deletions packages/sdk/react-native/example-fdv2/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { MOBILE_KEY } from '@env';

import {
AutoEnvAttributes,
LDProvider,
ReactNativeLDClient,
} from '@launchdarkly/react-native-client-sdk';

import Welcome from './src/welcome';

const featureClient = new ReactNativeLDClient(MOBILE_KEY, AutoEnvAttributes.Enabled, {
debug: true,
applicationInfo: {
id: 'ld-rn-fdv2-test-app',
version: '0.0.1',
},
// @ts-ignore dataSystem is @internal
dataSystem: {},
});

const App = () => (
<LDProvider client={featureClient}>
<Welcome />
</LDProvider>
);

export default App;
57 changes: 57 additions & 0 deletions packages/sdk/react-native/example-fdv2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# LaunchDarkly React Native SDK - FDv2 Example App

This is a minimal example app that demonstrates the experimental FDv2 data system
for the React Native SDK.

> **Note:** FDv2 support is `@internal` and experimental. It is not ready for
> production use and may change or be removed without notice.

## Features Demonstrated

- SDK initialization with the `dataSystem` option (FDv2 protocol)
- Connection mode switching for all FDv2 modes:
- **Streaming** - real-time flag updates with polling fallback
- **Polling** - periodic polling only
- **Offline** - cached flags only, no network
- **One-Shot** - initialize then stop (no persistent synchronizer)
- **Background** - low-frequency polling for background state
- **Automatic** - clear the override and use automatic mode selection
- Context identification
- Boolean flag evaluation

## Quickstart

1. At the js-core repo root, install dependencies and build:

```shell
yarn && yarn build
```

2. Create an `.env` file in this directory (`example-fdv2/`) with your mobile key:

```shell
MOBILE_KEY=mob-your-mobile-key-here
```

3. Update the flag key in `src/welcome.tsx` if needed (defaults to `sample-feature`).

4. Run the app:

```shell
# iOS
yarn ios

# Android
yarn android
```

> **Note:** You may need to run `npx expo prebuild` before the first iOS or
> Android build.

## Caveats

- **Network-based automatic mode switching** is not yet implemented. The wiring
is in place, but `RNStateDetector` does not yet emit network state changes.
Lifecycle-based switching (foreground/background) works.
- The `dataSystem` option and `setConnectionMode()` are marked `@internal` and
require `@ts-ignore` to use from TypeScript.
20 changes: 20 additions & 0 deletions packages/sdk/react-native/example-fdv2/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"expo": {
"name": "react-native-example-fdv2",
"slug": "react-native-example-fdv2",
"version": "1.0.0",
"orientation": "portrait",
"userInterfaceStyle": "light",
"assetBundlePatterns": ["**/*"],
"ios": {
"supportsTablet": true,
"bundleIdentifier": "com.anonymous.reactnativeexamplefdv2"
},
"android": {
"adaptiveIcon": {
"backgroundColor": "#ffffff"
},
"package": "com.anonymous.reactnativeexamplefdv2"
}
}
}
15 changes: 15 additions & 0 deletions packages/sdk/react-native/example-fdv2/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = function (api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
plugins: [
[
'module:react-native-dotenv',
{
safe: true,
allowUndefined: false,
},
],
],
};
};
10 changes: 10 additions & 0 deletions packages/sdk/react-native/example-fdv2/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// We have to use a custom entrypoint for monorepo workspaces to work.
// https://docs.expo.dev/guides/monorepos/#change-default-entrypoint
import { registerRootComponent } from 'expo';

import App from './App';

// registerRootComponent calls AppRegistry.registerComponent('main', () => App);
// It also ensures that whether you load the app in Expo Go or in a native build,
// the environment is set up appropriately
registerRootComponent(App);
26 changes: 26 additions & 0 deletions packages/sdk/react-native/example-fdv2/metro.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// We need to use a custom metro config for monorepo workspaces to work.
// https://docs.expo.dev/guides/monorepos/#modify-the-metro-config
/**
* @type {import('expo/metro-config')}
*/
const { getDefaultConfig } = require('expo/metro-config');
const path = require('path');

// Find the project and workspace directories
const projectRoot = __dirname;
// This can be replaced with `find-yarn-workspace-root`
const workspaceRoot = path.resolve(projectRoot, '../../../..');

const config = getDefaultConfig(projectRoot);

// 1. Watch all files within the monorepo
config.watchFolders = [workspaceRoot];
// 2. Let Metro know where to resolve packages and in what order
config.resolver.nodeModulesPaths = [
path.resolve(projectRoot, 'node_modules'),
path.resolve(workspaceRoot, 'node_modules'),
];
// 3. Force Metro to resolve (sub)dependencies only from the `nodeModulesPaths`
config.resolver.disableHierarchicalLookup = true;

module.exports = config;
31 changes: 31 additions & 0 deletions packages/sdk/react-native/example-fdv2/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "@launchdarkly/react-native-example-fdv2",
"private": true,
"version": "0.0.1",
"main": "index.js",
"scripts": {
"start": "expo start --reset-cache",
"android": "expo run:android",
"ios": "expo run:ios",
"web": "expo start --web --clear"
},
"dependencies": {
"@launchdarkly/react-native-client-sdk": "10.15.2",
Comment thread
devin-ai-integration[bot] marked this conversation as resolved.
Outdated
"@react-native-async-storage/async-storage": "^2.0.0",
"expo": "52.0.14",
"expo-status-bar": "~1.11.1",
"react": "18.3.1",
"react-native": "0.76.3",
"react-native-dotenv": "^3.4.9"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@types/react": "~18.2.55",
"@types/react-native-dotenv": "^0.2.1",
"typescript": "^5.2.2"
},
"packageManager": "yarn@3.4.1",
"installConfig": {
"hoistingLimits": "workspaces"
}
}
Comment thread
cursor[bot] marked this conversation as resolved.
Comment thread
cursor[bot] marked this conversation as resolved.
Loading
Loading