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

More api features #8

Merged
merged 4 commits into from
Apr 7, 2021
Merged
Show file tree
Hide file tree
Changes from all 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
36 changes: 33 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ True if Flagsmith has been configured to use a specific identity when resolving

See [identify](#identify) for more information.

### isListening: *boolean*

True if Flagsmith is configured to listen for updates. See [startListening](#startListening) for more details.

### isError: *boolean*

True if the Flagsmith integration is in an errored state (e.g. the server could not be reached). False otherwise.
Expand All @@ -121,7 +125,15 @@ True if the Flagsmith integration is in an errored state (e.g. the server could
await identify(identity)
```

Passes the supplied identity to the Flagsmith backend to be used when resolving feature flags and remote configuration. This causes an update in the state, which is an async action. Use the [isIdentified](isIdentified) flag to determine when the state has been re-loaded.
Passes the supplied identity to the Flagsmith backend to be used when resolving feature flags and remote configuration. This causes an update in the state, which is an async action. Use the [isIdentified](#isIdentified) flag to determine when the state has been re-loaded, or use [subscribe](#subscribe) to receive an update notification.

### logout

```javascript
await logout()
```

Remove any identifty associated with the Flagsmith client. Use the [isIdentified](#isIdentified) flag to determine when the state has been re-loaded, or use [subscribe](#subscribe) to receive an update notification.

### hasFeature

Expand All @@ -133,13 +145,31 @@ Determines is the feature specified `key` is set or not.

### getValue

```
```javascript
getValue(key)
```

Gets the current value of the remote configuration item specified by the `key`.

### subscribe(callback)
### startListening

```javascript
startListening(interval = 1000)
```
Begin listening for backend configuration changes. The polling interval is specified in mS. Use [isListening](#isListening) to determine the current listening state, and [subscribe](#subscribe) to be notified of updates.

### stopListeing

```javascript
stopListening()
```
Stop listening (polling) for configuration changes.

### subscribe

```javascript
subscribe(callback)
```

Registers a callback with Flagsmith that will be triggered any time a new configuration is available, for example after loading is complete, or when a new user is identified. This can be used to update any configuration state in components using Flagsmith, per the following example.

Expand Down
15 changes: 14 additions & 1 deletion __tests__/reducer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { reducer } from '../src/reducer'
const initialState = {
isLoading: true,
isError: false,
isIdentified: false
isIdentified: false,
isListening: false
}

describe('reducer', () => {
Expand Down Expand Up @@ -32,6 +33,18 @@ describe('reducer', () => {
expect(newState).toEqual({...initialState, isLoading: false, isIdentified: false})
})

test('can listen', () =>{
const newState = reducer({...initialState}, {type: 'START_LISTENING'})

expect(newState).toEqual({...initialState, isListening: true})
})

test('can stop listening', () => {
const newState = reducer({...initialState, isListening: true}, {type: 'STOP_LISTENING'})

expect(newState).toEqual({...initialState, isListening: false})
})

test('can be errored', () => {
const newState = reducer({...initialState}, {type: 'ERRORED'})

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "flagsmith-react",
"version": "0.0.3-alpha.1",
"version": "0.0.4-alpha.1",
"preview": true,
"description": "Flagsmith integration for React Single Page Applications (SPA)",
"repository": {
Expand Down
36 changes: 34 additions & 2 deletions src/flagsmith-provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useEventEmitter } from './use-event-emitter'

const FlagsmithProvider = ({ environmentId, children }) => {

const [state, dispatch] = useReducer(reducer, { isLoading: true, isError: false, isIdentified: false })
const [state, dispatch] = useReducer(reducer, { isLoading: true, isError: false, isIdentified: false, isListening: false })
const { emit, useSubscription } = useEventEmitter()

const handleChange = useCallback(e => emit(e), [emit])
Expand Down Expand Up @@ -41,6 +41,30 @@ const FlagsmithProvider = ({ environmentId, children }) => {
}, []
)

const logout = useCallback(
async () => {
try {
await flagsmith.logout()
} finally {
dispatch({type: 'UNIDENTIFIED'})
}
}, []
)

const startListening = useCallback(
(interval = 1000) => {
flagsmith.startListening(interval)
dispatch({type: 'START_LISTENING'})
}, []
)

const stopListening = useCallback(
() => {
flagsmith.stopListening()
dispatch({type: 'STOP_LISTENING'})
}, []
)

const hasFeature = useCallback(
(key) => {
return flagsmith.hasFeature(key)
Expand All @@ -54,7 +78,15 @@ const FlagsmithProvider = ({ environmentId, children }) => {
)

return (
<FlagsmithContext.Provider value={{...state, identify, hasFeature, getValue, subscribe: useSubscription}}>
<FlagsmithContext.Provider value={{
...state,
identify,
hasFeature,
getValue,
subscribe: useSubscription,
logout,
startListening,
stopListening}}>
{children}
</FlagsmithContext.Provider>
)
Expand Down
6 changes: 6 additions & 0 deletions src/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ export const reducer = (state, action) => {
case 'ERRORED': {
return {...state, isLoading: false, isError: true}
}
case 'START_LISTENING': {
return {...state, isListening: true}
}
case 'STOP_LISTENING': {
return {...state, isListening: false}
}
default: {
return {...state}
}
Expand Down