Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: rn sdk use localstorage for bootstrapping #326

Merged
merged 42 commits into from
Dec 22, 2023
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
85c41f8
chore: Added Storage api.
yusinto Dec 5, 2023
6c7f556
chore: replace connecting with initializing
yusinto Dec 11, 2023
7bf3327
chore: added type LDFlagChangeset. Fix storage set signature.
yusinto Dec 11, 2023
d95df72
chore: added fast-deep-equal. removed unused api methods.
yusinto Dec 11, 2023
e2f3cb4
chore: added skeleton to sync cached and put flags.
yusinto Dec 11, 2023
bc4e3de
chore: implement storage and put sync logic
yusinto Dec 11, 2023
63e6d3c
fix: export platform.Storage.
yusinto Dec 11, 2023
682e3ea
chore: implemented rn storage platform.
yusinto Dec 11, 2023
269b02f
chore: add local copy of fast-deep-equal. add storage tests.
yusinto Dec 13, 2023
8493374
fix: fixed hanging unit tests due to emits not being awaited. added m…
yusinto Dec 13, 2023
470a3fc
chore: added community rn async storage package.
yusinto Dec 13, 2023
460507a
fix: added internalOptions to configure events and diagnostic endpoin…
yusinto Dec 14, 2023
6a62c6a
fix: make internalOptions optional and fixed unit tests. removed redu…
yusinto Dec 14, 2023
ed4bb3a
chore: add unit test for internal options.
yusinto Dec 14, 2023
9f5eb03
fix: fix bug where change event emits wrong flag values. added versio…
yusinto Dec 15, 2023
b281b38
fix: when syncing only update memory cache and storage if there's cha…
yusinto Dec 15, 2023
78074fa
chore: added more patch unit tests.
yusinto Dec 15, 2023
34ad378
chore: added delete unit tests.
yusinto Dec 15, 2023
371351c
Update LDClientImpl.ts
yusinto Dec 15, 2023
30f5ace
chore: pretty print json debug output.
yusinto Dec 15, 2023
92361aa
fix: sse patch now updates react context. improved logging. TODO: fix…
yusinto Dec 16, 2023
78dc729
chore: added TODO comment.
yusinto Dec 16, 2023
7283b39
fix: remove unnecessary event listeners to fix infinite loops on errors.
yusinto Dec 18, 2023
ad0f124
chore: catch identify errors.
yusinto Dec 18, 2023
80cc003
chore: improved example.
yusinto Dec 18, 2023
6791a37
Update fetchUtils.test.ts
yusinto Dec 18, 2023
a0f916a
chore: improve npm commands.
yusinto Dec 18, 2023
8c19529
chore: remove async-storage dep from package.json
yusinto Dec 18, 2023
02f5c36
chore: added comments on how to install async-storage.
yusinto Dec 18, 2023
42c3bc6
chore: remove redundant ts-ignore
yusinto Dec 18, 2023
acd16db
chore: improved logging, cleaned up comments, added comments, removed…
yusinto Dec 19, 2023
87d09ba
chore: improve logging.
yusinto Dec 19, 2023
713221e
chore: localstorage pr feedback (#327)
yusinto Dec 20, 2023
87ca38b
chore: include example/yarn.lock because the example app is its own i…
yusinto Dec 20, 2023
c849f8c
Update .gitignore
yusinto Dec 20, 2023
55e664c
chore: improve readme and npm commands for dev.
yusinto Dec 21, 2023
f35bada
chore: replace process.nextTick with setTimeout.
yusinto Dec 21, 2023
597e439
chore: remove .only.
yusinto Dec 21, 2023
eb61ced
chore: further improve readme. include instructions for .env.
yusinto Dec 22, 2023
58f72c1
fix: stream delete command should only delete lower versions, not equal.
yusinto Dec 22, 2023
d8a4cbb
chore: implement tombstoning (#328)
yusinto Dec 22, 2023
382e519
Merge branch 'main' into yus/sc-225809/use-localstorage-for-bootstrap…
yusinto Dec 22, 2023
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
72 changes: 67 additions & 5 deletions packages/sdk/react-native/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# LaunchDarkly React Native SDK

:warning: UNSUPPORTED This SDK is in pre-release development and is not supported.
> [!WARNING]
> UNSUPPORTED This SDK is in pre-release development and is not supported.

[![NPM][sdk-react-native-npm-badge]][sdk-react-native-npm-link]
[![Actions Status][sdk-react-native-ci-badge]][sdk-react-native-ci]
Expand All @@ -20,19 +21,80 @@ For more information, see the [complete reference guide for this SDK](https://do
yarn add @launchdarkly/react-native-client-sdk
```

Additionally, the LaunchDarkly React-Native SDK uses
[@react-native-async-storage/async-storage](https://github.com/react-native-async-storage/async-storage)
for bootstrapping. This is a native dependency.

If you are using expo, then installing this package from npm like above and re-running pod install should suffice.

If you are not using expo, you will need to explicitly add
@react-native-async-storage/async-storage as a dependency to your project
and re-run pod install for [auto-linking to work](https://github.com/react-native-community/cli/issues/1347).

## Quickstart

TODO
1. Wrap your application with `LDProvider` passing it an LDClient and
an LDContext:

```jsx
// App.tsx
import { LDProvider, ReactNativeLDClient } from '@launchdarkly/react-native-client-sdk';

const featureClient = new ReactNativeLDClient('mobile-key');
const userContext = { kind: 'user', key: 'test-user-1' };

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

export default App;
```

2. Then in a child component, evaluate flags with `useBoolVariation`:

```jsx
import { useBoolVariation } from '@launchdarkly/react-native-client-sdk';

export default function Welcome() {
const flagValue = useBoolVariation('flag-key', false);

```typescript
// TODO
return (
<View style={styles.container}>
<Text>Welcome to LaunchDarkly</Text>
<Text>Flag value is {`${flagValue}`}</Text>
</View>
);
}
```

See the full [example app](https://github.com/launchdarkly/js-core/tree/main/packages/sdk/react-native/example).

## Developing this SDK

:information_source: See the example [README](https://github.com/launchdarkly/js-core/blob/main/packages/sdk/react-native/example/README.md#L1).
1. Build all the code in the `js-core` repo:

```shell
# at js-core repo root
yarn && yarn build
```

2. The example app uses [react-native-dotenv](https://github.com/goatandsheep/react-native-dotenv)
to manage environment variables. Under `packages/sdk/react-native/example`
create an `.env` file and add your mobile key:

```shell
echo "MOBILE_KEY=mob-abc" >> packages/sdk/react-native/example/.env
```

3. Run the example app. This will link the local react-native sdk code to the
example app for development:

```shell
# in react-native/example
yarn && yarn ios-go
```

## About LaunchDarkly

Expand Down
2 changes: 2 additions & 0 deletions packages/sdk/react-native/example/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,5 @@ yarn-error.*

ios
android

!yarn.lock
3 changes: 1 addition & 2 deletions packages/sdk/react-native/example/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ import { LDProvider, ReactNativeLDClient } from '@launchdarkly/react-native-clie
import Welcome from './src/welcome';

const featureClient = new ReactNativeLDClient(MOBILE_KEY);
const context = { kind: 'user', key: 'test-user-1' };

const App = () => {
return (
<LDProvider client={featureClient} context={context}>
<LDProvider client={featureClient}>
<Welcome />
</LDProvider>
);
Expand Down
8 changes: 4 additions & 4 deletions packages/sdk/react-native/example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ MOBILE_KEY=abcdef12456

```shell
# Note for android, there's an issue with Flipper interfering with streaming connections
# so please run the release build. There's no such issue with ios.

# android
yarn && yarn android-release
# so please run the release build. There's no such issues with ios.

# ios
yarn && yarn ios-go

# android
yarn && yarn android-release
```
18 changes: 10 additions & 8 deletions packages/sdk/react-native/example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@
"scripts": {
"start": "expo start",
"expo-clean": "expo prebuild --clean",
"android": "expo run:android",
"android-release": "expo run:android --variant release",
"android-go": "expo start --android --clear",
"android": "yarn link-dev && expo run:android",
"android-release": "yarn link-dev && expo run:android --variant release",
"android-go": "yarn link-dev && expo start --android --clear",
"android-log": "react-native log-android",
"ios": "expo run:ios",
"ios-release": "expo run:ios --configuration Release",
"ios-go": "expo start --ios --clear",
"ios": "yarn link-dev && expo run:ios",
"ios-release": "yarn link-dev && expo run:ios --configuration Release",
"ios-go": "yarn link-dev && expo start --ios --clear",
"ios-log": "react-native log-ios",
"web": "expo start --web --clear",
"clean": "expo prebuild --clean && yarn cache clean && rm -rf node_modules && rm -rf .expo"
"web": "yarn link-dev && expo start --web --clear",
"clean": "expo prebuild --clean && yarn cache clean && rm -rf node_modules && rm -rf .expo",
"link-dev": "(cd .. && yarn build)",
"postinstall": "yarn link-dev"
},
"dependencies": {
"expo": "~49.0.16",
Expand Down
70 changes: 52 additions & 18 deletions packages/sdk/react-native/example/src/welcome.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,46 @@
import { Button, StyleSheet, Text, View } from 'react-native';
import { useState } from 'react';
import { StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native';

import {
useBoolVariation,
useLDClient,
useLDDataSourceStatus,
} from '@launchdarkly/react-native-client-sdk';
import { useBoolVariation, useLDClient } from '@launchdarkly/react-native-client-sdk';

export default function Welcome() {
const { error, status } = useLDDataSourceStatus();
const flag = useBoolVariation('dev-test-flag', false);
const [flagKey, setFlagKey] = useState('dev-test-flag');
const [userKey, setUserKey] = useState('');
const flagValue = useBoolVariation(flagKey, false);
const ldc = useLDClient();

const login = () => {
ldc.identify({ kind: 'user', key: 'test-user-2' });
const onIdentify = () => {
ldc
.identify({ kind: 'user', key: userKey })
.catch((e: any) => console.error(`error identifying ${userKey}: ${e}`));
};

return (
<View style={styles.container}>
<Text>Welcome to LaunchDarkly</Text>
<Text>status: {status ?? 'not connected'}</Text>
{error ? <Text>error: {error.message}</Text> : null}
<Text>devTestFlag: {`${flag}`}</Text>
<Text>
{flagKey}: {`${flagValue}`}
</Text>
<Text>context: {JSON.stringify(ldc.getContext())}</Text>
<Button title="Login" onPress={login} />
<TextInput
style={styles.input}
autoCapitalize="none"
onChangeText={setUserKey}
onSubmitEditing={onIdentify}
value={userKey}
/>
<TouchableOpacity onPress={onIdentify} style={styles.buttonContainer}>
<Text style={styles.buttonText}>identify</Text>
</TouchableOpacity>
<TextInput
style={styles.input}
autoCapitalize="none"
onChangeText={setFlagKey}
value={flagKey}
/>
<TouchableOpacity style={styles.buttonContainer}>
<Text style={styles.buttonText}>get flag value</Text>
</TouchableOpacity>
</View>
);
}
Expand All @@ -33,9 +51,25 @@ const styles = StyleSheet.create({
alignItems: 'center',
justifyContent: 'center',
},
box: {
width: 60,
height: 60,
marginVertical: 20,
input: {
height: 40,
margin: 12,
borderWidth: 1,
padding: 10,
},
buttonContainer: {
elevation: 8,
backgroundColor: '#009688',
borderRadius: 10,
paddingVertical: 10,
paddingHorizontal: 12,
marginBottom: 20,
},
buttonText: {
fontSize: 18,
color: '#fff',
fontWeight: 'bold',
alignSelf: 'center',
textTransform: 'uppercase',
},
});
Loading