@harnessio/ff-react-client-sdk
Advanced tools
Comparing version 1.14.0 to 2.0.0-rc.0
import { FC, PropsWithChildren, ReactNode } from 'react'; | ||
import { Evaluation, Event as FFEvent, Options, Result as InitializeResult, Target, DefaultVariationEventPayload } from '@harnessio/ff-javascript-client-sdk'; | ||
import { Evaluation, Event as FFEvent, Options, Result as InitializeResult, Target } from '@harnessio/ff-javascript-client-sdk'; | ||
export interface FFContextValue { | ||
@@ -18,4 +18,3 @@ loading: boolean; | ||
onError?: (event: NetworkError | 'PropsError', error?: unknown) => void; | ||
onFlagNotFound?: (flagNotFound: DefaultVariationEventPayload, loading: boolean) => void; | ||
} | ||
export declare const FFContextProvider: FC<FFContextProviderProps>; |
@@ -12,8 +12,6 @@ "use strict"; | ||
exports.FFContext = (0, react_1.createContext)({}); | ||
const FFContextProvider = ({ children, apiKey, target, options = {}, fallback = (0, jsx_runtime_1.jsx)("p", { children: "Loading..." }), async = false, initialEvaluations, onError = () => void 0, onFlagNotFound = () => void 0 }) => { | ||
const FFContextProvider = ({ children, apiKey, target, options = {}, fallback = (0, jsx_runtime_1.jsx)("p", { children: "Loading..." }), async = false, initialEvaluations, onError = () => void 0 }) => { | ||
const [loading, setLoading] = (0, react_1.useState)(true); | ||
const [flags, setFlags] = (0, react_1.useState)({}); | ||
const [clientInstance, setClientInstance] = (0, react_1.useState)(); | ||
// Use a reference to keep track of the latest loading state so we can use it with event callbacks. | ||
const loadingRef = (0, react_1.useRef)(true); | ||
(0, react_1.useEffect)(() => { | ||
@@ -35,7 +33,5 @@ if (!apiKey) { | ||
setLoading(true); | ||
loadingRef.current = true; | ||
setClientInstance(client); | ||
const onInitialLoad = (newFlags) => { | ||
setLoading(false); | ||
loadingRef.current = false; | ||
setFlags(newFlags); | ||
@@ -58,5 +54,2 @@ client.on(ff_javascript_client_sdk_1.Event.CHANGED, onFlagChange); | ||
}; | ||
const onFlagNotFoundListener = ({ flag, defaultVariation }) => { | ||
onFlagNotFound({ flag, defaultVariation }, loadingRef.current); | ||
}; | ||
const onAuthError = onNetworkError(ff_javascript_client_sdk_1.Event.ERROR_AUTH); | ||
@@ -73,3 +66,2 @@ const onStreamError = onNetworkError(ff_javascript_client_sdk_1.Event.ERROR_STREAM); | ||
client.on(ff_javascript_client_sdk_1.Event.ERROR_METRICS, onMetricsError); | ||
client.on(ff_javascript_client_sdk_1.Event.ERROR_DEFAULT_VARIATION_RETURNED, onFlagNotFoundListener); | ||
if (initialEvaluations) { | ||
@@ -86,3 +78,2 @@ client.setEvaluations(initialEvaluations); | ||
client.off(ff_javascript_client_sdk_1.Event.ERROR_METRICS, onMetricsError); | ||
client.off(ff_javascript_client_sdk_1.Event.ERROR_DEFAULT_VARIATION_RETURNED, onFlagNotFoundListener); | ||
client.close(); | ||
@@ -89,0 +80,0 @@ }; |
import { FC, PropsWithChildren, ReactNode } from 'react'; | ||
import { Evaluation, Event as FFEvent, Options, Result as InitializeResult, Target, DefaultVariationEventPayload } from '@harnessio/ff-javascript-client-sdk'; | ||
import { Evaluation, Event as FFEvent, Options, Result as InitializeResult, Target } from '@harnessio/ff-javascript-client-sdk'; | ||
export interface FFContextValue { | ||
@@ -18,4 +18,3 @@ loading: boolean; | ||
onError?: (event: NetworkError | 'PropsError', error?: unknown) => void; | ||
onFlagNotFound?: (flagNotFound: DefaultVariationEventPayload, loading: boolean) => void; | ||
} | ||
export declare const FFContextProvider: FC<FFContextProviderProps>; |
import { jsx as _jsx } from "react/jsx-runtime"; | ||
import { createContext, useEffect, useRef, useState } from 'react'; | ||
import { createContext, useEffect, useState } from 'react'; | ||
import { Event as FFEvent, initialize } from '@harnessio/ff-javascript-client-sdk'; | ||
import omit from 'lodash.omit'; | ||
export const FFContext = createContext({}); | ||
export const FFContextProvider = ({ children, apiKey, target, options = {}, fallback = _jsx("p", { children: "Loading..." }), async = false, initialEvaluations, onError = () => void 0, onFlagNotFound = () => void 0 }) => { | ||
export const FFContextProvider = ({ children, apiKey, target, options = {}, fallback = _jsx("p", { children: "Loading..." }), async = false, initialEvaluations, onError = () => void 0 }) => { | ||
const [loading, setLoading] = useState(true); | ||
const [flags, setFlags] = useState({}); | ||
const [clientInstance, setClientInstance] = useState(); | ||
// Use a reference to keep track of the latest loading state so we can use it with event callbacks. | ||
const loadingRef = useRef(true); | ||
useEffect(() => { | ||
@@ -28,7 +26,5 @@ if (!apiKey) { | ||
setLoading(true); | ||
loadingRef.current = true; | ||
setClientInstance(client); | ||
const onInitialLoad = (newFlags) => { | ||
setLoading(false); | ||
loadingRef.current = false; | ||
setFlags(newFlags); | ||
@@ -51,5 +47,2 @@ client.on(FFEvent.CHANGED, onFlagChange); | ||
}; | ||
const onFlagNotFoundListener = ({ flag, defaultVariation }) => { | ||
onFlagNotFound({ flag, defaultVariation }, loadingRef.current); | ||
}; | ||
const onAuthError = onNetworkError(FFEvent.ERROR_AUTH); | ||
@@ -66,3 +59,2 @@ const onStreamError = onNetworkError(FFEvent.ERROR_STREAM); | ||
client.on(FFEvent.ERROR_METRICS, onMetricsError); | ||
client.on(FFEvent.ERROR_DEFAULT_VARIATION_RETURNED, onFlagNotFoundListener); | ||
if (initialEvaluations) { | ||
@@ -79,3 +71,2 @@ client.setEvaluations(initialEvaluations); | ||
client.off(FFEvent.ERROR_METRICS, onMetricsError); | ||
client.off(FFEvent.ERROR_DEFAULT_VARIATION_RETURNED, onFlagNotFoundListener); | ||
client.close(); | ||
@@ -82,0 +73,0 @@ }; |
{ | ||
"name": "@harnessio/ff-react-client-sdk", | ||
"version": "1.14.0", | ||
"version": "2.0.0-rc.0", | ||
"author": "Harness", | ||
@@ -5,0 +5,0 @@ "license": "Apache-2.0", |
@@ -105,13 +105,13 @@ # React.js Client SDK For Harness Feature Flags | ||
may be beneficial to immediately render the application and handle display of loading on a component-by-component basis. | ||
The React Client SDK's asynchronous mode allows this by passing the optional `async` prop when connecting with the | ||
The React Client SDK's asynchronous mode allows this by passing the optional `asyncMode` prop when connecting with the | ||
`FFContextProvider`. | ||
## On Flag Not Found | ||
The `onFlagNotFound` option allows you to handle situations where a default variation is returned. | ||
It includes the flag, variation, and whether the SDK was still initializing (`loading)` when the default was served. | ||
The `onFlagNotFound` option allows you to handle situations where a default variation is returned. | ||
It includes the flag, variation, and whether the SDK was still initializing (`loading)` when the default was served. | ||
This can happen when: | ||
1. Using `async` mode without `cache` or `initialEvaluations` and where the SDK is still initializing. | ||
1. Using `asyncMode` without `cache` or `initialEvaluations` and where the SDK is still initializing. | ||
2. The flag identifier is incorrect (e.g., due to a typo). | ||
@@ -129,5 +129,9 @@ 3. The wrong API key is being used, and the expected flags are not available for that project. | ||
if (loading) { | ||
console.debug(`Flag "${flagNotFound.flag}" not found because the SDK is still initializing. Returned default: ${flagNotFound.defaultVariation}`); | ||
console.debug( | ||
`Flag "${flagNotFound.flag}" not found because the SDK is still initializing. Returned default: ${flagNotFound.defaultVariation}` | ||
) | ||
} else { | ||
console.warn(`Flag "${flagNotFound.flag}" not found. Returned default: ${flagNotFound.defaultVariation}`); | ||
console.warn( | ||
`Flag "${flagNotFound.flag}" not found. Returned default: ${flagNotFound.defaultVariation}` | ||
) | ||
} | ||
@@ -138,6 +142,6 @@ }} | ||
</FFContextProvider> | ||
``` | ||
By using the `onFlagNotFound` prop, your application can be notified whenever a flag is missing and the default variation has been returned. | ||
By using the `onFlagNotFound` prop, your application can be notified whenever a flag is missing and the default | ||
variation has been returned. | ||
@@ -238,3 +242,4 @@ ## Caching evaluations | ||
The `FFContextProvider` component also accepts an `options` object, a `fallback` component, an array | ||
of `initialEvaluations`, an `onError` handler, and can be placed in [Async mode](#Async-mode) using the `async` prop. | ||
of `initialEvaluations`, an `onError` handler, and can be placed in [Async mode](#Async-mode) using the `asyncMode` | ||
prop. | ||
The `fallback` component will be displayed while the SDK is connecting and fetching your flags. The `initialEvaluations` | ||
@@ -252,3 +257,3 @@ prop allows you pass an array of evaluations to use immediately as the SDK is authenticating and fetching flags. | ||
<FFContextProvider | ||
async={false} // OPTIONAL: whether or not to use async mode | ||
asyncMode={false} // OPTIONAL: whether or not to use async mode | ||
apiKey="YOUR_API_KEY" // your SDK API key | ||
@@ -255,0 +260,0 @@ target={{ |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
578
58212
47
551
1