Skip to content

Commit def3fe8

Browse files
authored
chore: add js docs for context mutator hook (#1045)
Minor refactors, but mostly adding js-doc after #1031. --------- Signed-off-by: Todd Baert <[email protected]>
1 parent ec3d967 commit def3fe8

File tree

13 files changed

+69
-54
lines changed

13 files changed

+69
-54
lines changed

packages/react/src/provider/context.ts renamed to packages/react/src/common/context.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { Client } from '@openfeature/web-sdk';
22
import React from 'react';
3-
import type { NormalizedOptions, ReactFlagEvaluationOptions} from '../common/options';
4-
import { normalizeOptions } from '../common/options';
3+
import type { NormalizedOptions, ReactFlagEvaluationOptions} from '../common';
4+
import { normalizeOptions } from '../common';
55

66
/**
77
* The underlying React context.

packages/react/src/common/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export * from './context';
2+
export * from './is-equal';
3+
export * from './options';
4+
export * from './suspense';

packages/react/src/context/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './use-context-mutator';
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { useCallback, useContext, useRef } from 'react';
2+
import type { EvaluationContext } from '@openfeature/web-sdk';
3+
import { OpenFeature } from '@openfeature/web-sdk';
4+
import { Context } from '../common';
5+
6+
export type ContextMutationOptions = {
7+
/**
8+
* Mutate the default context instead of the domain scoped context applied at the `<OpenFeatureProvider/>`.
9+
* Note, if the `<OpenFeatureProvider/>` has no domain specified, the default is used.
10+
* See the {@link https://openfeature.dev/docs/reference/technologies/client/web/#manage-evaluation-context-for-domains|documentation} for more information.
11+
* @default false
12+
*/
13+
defaultContext?: boolean;
14+
};
15+
16+
export type ContextMutation = {
17+
/**
18+
* A function to set the desired context (see: {@link ContextMutationOptions} for details).
19+
* There's generally no need to await the result of this function; flag evaluation hooks will re-render when the context is updated.
20+
* This promise never rejects.
21+
* @param updatedContext
22+
* @returns Promise for awaiting the context update
23+
*/
24+
setContext: (updatedContext: EvaluationContext) => Promise<void>;
25+
};
26+
27+
/**
28+
* Get function(s) for mutating the evaluation context associated with this domain, or the default context if `defaultContext: true`.
29+
* See the {@link https://openfeature.dev/docs/reference/technologies/client/web/#targeting-and-context|documentation} for more information.
30+
* @param {ContextMutationOptions} options options for the generated function
31+
* @returns {ContextMutation} function(s) to mutate context
32+
*/
33+
export function useContextMutator(options: ContextMutationOptions = { defaultContext: false }): ContextMutation {
34+
const { domain } = useContext(Context) || {};
35+
const previousContext = useRef<null | EvaluationContext>(null);
36+
37+
const setContext = useCallback(async (updatedContext: EvaluationContext) => {
38+
if (previousContext.current !== updatedContext) {
39+
if (!domain || options?.defaultContext) {
40+
OpenFeature.setContext(updatedContext);
41+
} else {
42+
OpenFeature.setContext(domain, updatedContext);
43+
}
44+
previousContext.current = updatedContext;
45+
}
46+
}, [domain]);
47+
48+
return {
49+
setContext,
50+
};
51+
}

packages/react/src/evaluation/use-feature-flag.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,12 @@ import {
1111
ProviderStatus,
1212
} from '@openfeature/web-sdk';
1313
import { useEffect, useRef, useState } from 'react';
14-
import type { ReactFlagEvaluationOptions} from '../common/options';
15-
import { DEFAULT_OPTIONS, normalizeOptions } from '../common/options';
16-
import { suspendUntilReady } from '../common/suspense';
17-
import { useProviderOptions } from '../provider/context';
14+
import type { ReactFlagEvaluationOptions} from '../common';
15+
import { DEFAULT_OPTIONS, isEqual, normalizeOptions, suspendUntilReady, useProviderOptions } from '../common';
1816
import { useOpenFeatureClient } from '../provider/use-open-feature-client';
1917
import { useOpenFeatureClientStatus } from '../provider/use-open-feature-client-status';
2018
import type { FlagQuery } from '../query';
2119
import { HookFlagQuery } from './hook-flag-query';
22-
import { isEqual } from '../common/is-equal';
2320

2421
// This type is a bit wild-looking, but I think we need it.
2522
// We have to use the conditional, because otherwise useFlag('key', false) would return false, not boolean (too constrained).

packages/react/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export * from './evaluation';
22
export * from './query';
33
export * from './provider';
4+
export * from './context';
45
// re-export the web-sdk so consumers can access that API from the react-sdk
56
export * from '@openfeature/web-sdk';

packages/react/src/provider/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,3 @@ export * from './provider';
22
export * from './use-open-feature-client';
33
export * from './use-when-provider-ready';
44
export * from './test-provider';
5-
export * from './use-context-mutator';

packages/react/src/provider/provider.tsx

Lines changed: 2 additions & 2 deletions
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/options';
5-
import { Context } from './context';
4+
import type { ReactFlagEvaluationOptions } from '../common';
5+
import { Context } from '../common';
66

77
type ClientOrDomain =
88
| {

packages/react/src/provider/test-provider.tsx

Lines changed: 2 additions & 2 deletions
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/options';
10+
import type { NormalizedOptions } from '../common';
1111
import { OpenFeatureProvider } from './provider';
1212

1313
type FlagValueMap = { [flagKey: string]: JsonValue };
@@ -119,4 +119,4 @@ function mixInNoop(provider: Partial<Provider> = {}) {
119119
(provider.metadata as unknown) = { name: TEST_PROVIDER };
120120
}
121121
return provider;
122-
}
122+
}

packages/react/src/provider/use-context-mutator.ts

Lines changed: 0 additions & 36 deletions
This file was deleted.

0 commit comments

Comments
 (0)