Skip to content

Commit 16321c3

Browse files
authored
refactor: export public option types (open-feature#1101)
## This PR - renames the `shared` folder to `internal` to prevent accident exports - export public option types ### Notes This will make it easier for devs who need access to the option types. --------- Signed-off-by: Michael Beemer <[email protected]>
1 parent e335615 commit 16321c3

16 files changed

+112
-102
lines changed

Diff for: packages/react/src/common/options.ts

-83
This file was deleted.

Diff for: packages/react/src/context/use-context-mutator.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useCallback, useContext, useRef } from 'react';
22
import type { EvaluationContext } from '@openfeature/web-sdk';
33
import { OpenFeature } from '@openfeature/web-sdk';
4-
import { Context } from '../common';
4+
import { Context } from '../internal';
55

66
export type ContextMutationOptions = {
77
/**

Diff for: packages/react/src/evaluation/use-feature-flag.ts

+4-7
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import {
1111
ProviderStatus,
1212
} from '@openfeature/web-sdk';
1313
import { useEffect, useRef, useState } from 'react';
14-
import type { ReactFlagEvaluationOptions} from '../common';
15-
import { DEFAULT_OPTIONS, isEqual, normalizeOptions, suspendUntilReady, useProviderOptions } from '../common';
14+
import type { ReactFlagEvaluationNoSuspenseOptions, ReactFlagEvaluationOptions } from '../options';
15+
import { DEFAULT_OPTIONS, isEqual, normalizeOptions, suspendUntilReady, useProviderOptions } from '../internal';
1616
import { useOpenFeatureClient } from '../provider/use-open-feature-client';
1717
import { useOpenFeatureClientStatus } from '../provider/use-open-feature-client-status';
1818
import type { FlagQuery } from '../query';
@@ -33,9 +33,6 @@ type ConstrainedFlagQuery<T> = FlagQuery<
3333
: JsonValue
3434
>;
3535

36-
// suspense options removed for the useSuspenseFlag hooks
37-
type NoSuspenseOptions = Omit<ReactFlagEvaluationOptions, 'suspend' | 'suspendUntilReady' | 'suspendWhileReconciling'>;
38-
3936
/**
4037
* Evaluates a feature flag generically, returning an react-flavored queryable object.
4138
* The resolver method to use is based on the type of the defaultValue.
@@ -84,13 +81,13 @@ type UseFlagReturn<T extends FlagValue> = ReturnType<typeof useFlag<T>>;
8481
* @param {string} flagKey the flag identifier
8582
* @template {FlagValue} T A optional generic argument constraining the default.
8683
* @param {T} defaultValue the default value; used to determine what resolved type should be used.
87-
* @param {NoSuspenseOptions} options for this evaluation
84+
* @param {ReactFlagEvaluationNoSuspenseOptions} options for this evaluation
8885
* @returns { UseFlagReturn<T> } a queryable object containing useful information about the flag.
8986
*/
9087
export function useSuspenseFlag<T extends FlagValue = FlagValue>(
9188
flagKey: string,
9289
defaultValue: T,
93-
options?: NoSuspenseOptions,
90+
options?: ReactFlagEvaluationNoSuspenseOptions,
9491
): UseFlagReturn<T> {
9592
return useFlag(flagKey, defaultValue, { ...options, suspendUntilReady: true, suspendWhileReconciling: true });
9693
}

Diff for: packages/react/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ export * from './query';
33
export * from './provider';
44
export * from './context';
55
export * from './tracking';
6+
export * from './options';
67
// re-export the web-sdk so consumers can access that API from the react-sdk
78
export * from '@openfeature/web-sdk';

Diff for: packages/react/src/common/context.ts renamed to packages/react/src/internal/context.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import type { Client } from '@openfeature/web-sdk';
22
import React from 'react';
3-
import type { NormalizedOptions, ReactFlagEvaluationOptions} from '../common';
4-
import { normalizeOptions } from '../common';
3+
import type { NormalizedOptions, ReactFlagEvaluationOptions } from '../options';
4+
import { normalizeOptions } from '.';
55

66
/**
77
* The underlying React context.
88
* DO NOT EXPORT PUBLICLY
99
* @internal
1010
*/
11-
export const Context = React.createContext<{ client: Client; domain?: string; options: ReactFlagEvaluationOptions } | undefined>(undefined);
11+
export const Context = React.createContext<
12+
{ client: Client; domain?: string; options: ReactFlagEvaluationOptions } | undefined
13+
>(undefined);
1214

1315
/**
1416
* Get a normalized copy of the options used for this OpenFeatureProvider, see {@link normalizeOptions}.
File renamed without changes.
File renamed without changes.

Diff for: packages/react/src/internal/options.ts

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import type { ReactFlagEvaluationOptions, NormalizedOptions } from '../options';
2+
3+
/**
4+
* Default options.
5+
* DO NOT EXPORT PUBLICLY
6+
* @internal
7+
*/
8+
export const DEFAULT_OPTIONS: ReactFlagEvaluationOptions = {
9+
updateOnContextChanged: true,
10+
updateOnConfigurationChanged: true,
11+
suspendUntilReady: false,
12+
suspendWhileReconciling: false,
13+
};
14+
15+
/**
16+
* Returns normalization options (all `undefined` fields removed, and `suspend` decomposed to `suspendUntilReady` and `suspendWhileReconciling`).
17+
* DO NOT EXPORT PUBLICLY
18+
* @internal
19+
* @param {ReactFlagEvaluationOptions} options options to normalize
20+
* @returns {NormalizedOptions} normalized options
21+
*/
22+
export const normalizeOptions: (options?: ReactFlagEvaluationOptions) => NormalizedOptions = (
23+
options: ReactFlagEvaluationOptions = {},
24+
) => {
25+
const updateOnContextChanged = options.updateOnContextChanged;
26+
const updateOnConfigurationChanged = options.updateOnConfigurationChanged;
27+
28+
// fall-back the suspense options to the catch-all `suspend` property
29+
const suspendUntilReady = 'suspendUntilReady' in options ? options.suspendUntilReady : options.suspend;
30+
const suspendWhileReconciling =
31+
'suspendWhileReconciling' in options ? options.suspendWhileReconciling : options.suspend;
32+
33+
return {
34+
// only return these if properly set (no undefined to allow overriding with spread)
35+
...(typeof suspendUntilReady === 'boolean' && { suspendUntilReady }),
36+
...(typeof suspendWhileReconciling === 'boolean' && { suspendWhileReconciling }),
37+
...(typeof updateOnContextChanged === 'boolean' && { updateOnContextChanged }),
38+
...(typeof updateOnConfigurationChanged === 'boolean' && { updateOnConfigurationChanged }),
39+
};
40+
};
File renamed without changes.

Diff for: packages/react/src/options.ts

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import type { FlagEvaluationOptions } from '@openfeature/web-sdk';
2+
3+
export type ReactFlagEvaluationOptions = (
4+
| {
5+
/**
6+
* Enable or disable all suspense functionality.
7+
* Cannot be used in conjunction with `suspendUntilReady` and `suspendWhileReconciling` options.
8+
* @experimental Suspense is an experimental feature subject to change in future versions.
9+
*/
10+
suspend?: boolean;
11+
suspendUntilReady?: never;
12+
suspendWhileReconciling?: never;
13+
}
14+
| {
15+
/**
16+
* Suspend flag evaluations while the provider is not ready.
17+
* Set to false if you don't want to show suspense fallbacks until the provider is initialized.
18+
* Defaults to false.
19+
* Cannot be used in conjunction with `suspend` option.
20+
* @experimental Suspense is an experimental feature subject to change in future versions.
21+
*/
22+
suspendUntilReady?: boolean;
23+
/**
24+
* Suspend flag evaluations while the provider's context is being reconciled.
25+
* Set to true if you want to show suspense fallbacks while flags are re-evaluated after context changes.
26+
* Defaults to false.
27+
* Cannot be used in conjunction with `suspend` option.
28+
* @experimental Suspense is an experimental feature subject to change in future versions.
29+
*/
30+
suspendWhileReconciling?: boolean;
31+
suspend?: never;
32+
}
33+
) & {
34+
/**
35+
* Update the component if the provider emits a ConfigurationChanged event.
36+
* Set to false to prevent components from re-rendering when flag value changes
37+
* are received by the associated provider.
38+
* Defaults to true.
39+
*/
40+
updateOnConfigurationChanged?: boolean;
41+
/**
42+
* Update the component when the OpenFeature context changes.
43+
* Set to false to prevent components from re-rendering when attributes which
44+
* may be factors in flag evaluation change.
45+
* Defaults to true.
46+
*/
47+
updateOnContextChanged?: boolean;
48+
} & FlagEvaluationOptions;
49+
50+
// suspense options removed for the useSuspenseFlag hooks
51+
export type ReactFlagEvaluationNoSuspenseOptions = Omit<ReactFlagEvaluationOptions, 'suspend' | 'suspendUntilReady' | 'suspendWhileReconciling'>;
52+
53+
export type NormalizedOptions = Omit<ReactFlagEvaluationOptions, 'suspend'>;

Diff for: packages/react/src/provider/provider.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import type { Client} from '@openfeature/web-sdk';
22
import { OpenFeature } from '@openfeature/web-sdk';
33
import * as React from 'react';
4-
import type { ReactFlagEvaluationOptions } from '../common';
5-
import { Context } from '../common';
4+
import type { ReactFlagEvaluationOptions } from '../options';
5+
import { Context } from '../internal';
66

77
type ClientOrDomain =
88
| {

Diff for: packages/react/src/provider/test-provider.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
OpenFeature
88
} from '@openfeature/web-sdk';
99
import React from 'react';
10-
import type { NormalizedOptions } from '../common';
10+
import type { NormalizedOptions } from '../options';
1111
import { OpenFeatureProvider } from './provider';
1212

1313
type FlagValueMap = { [flagKey: string]: JsonValue };

Diff for: packages/react/src/provider/use-open-feature-client.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { Context } from '../common';
2+
import { Context } from '../internal';
33
import type { Client } from '@openfeature/web-sdk';
44

55
/**

Diff for: packages/react/src/provider/use-when-provider-ready.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { ProviderStatus } from '@openfeature/web-sdk';
22
import { useOpenFeatureClient } from './use-open-feature-client';
33
import { useOpenFeatureClientStatus } from './use-open-feature-client-status';
4-
import type { ReactFlagEvaluationOptions} from '../common';
5-
import { DEFAULT_OPTIONS, useProviderOptions, normalizeOptions, suspendUntilReady } from '../common';
4+
import type { ReactFlagEvaluationOptions } from '../options';
5+
import { DEFAULT_OPTIONS, useProviderOptions, normalizeOptions, suspendUntilReady } from '../internal';
66

77
type Options = Pick<ReactFlagEvaluationOptions, 'suspendUntilReady'>;
88

Diff for: packages/react/test/is-equal.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { isEqual } from '../src/common/is-equal';
1+
import { isEqual } from '../src/internal/is-equal';
22

33
describe('isEqual', () => {
44
it('should return true for equal primitive values', () => {

Diff for: packages/react/test/options.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { normalizeOptions } from '../src/common/options';
1+
import { normalizeOptions } from '../src/internal/options';
22

33
describe('normalizeOptions', () => {
44
// we spread results from this function, so we never want to return null

0 commit comments

Comments
 (0)