@openfeature/react-sdk 1.2.1 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,8 +16,8 @@
16
16
  <img alt="Specification" src="https://img.shields.io/static/v1?label=specification&message=v0.8.0&color=yellow&style=for-the-badge" />
17
17
  </a>
18
18
  <!-- x-release-please-start-version -->
19
- <a href="https://github.com/open-feature/js-sdk/releases/tag/react-sdk-v1.2.1">
20
- <img alt="Release" src="https://img.shields.io/static/v1?label=release&message=v1.2.1&color=blue&style=for-the-badge" />
19
+ <a href="https://github.com/open-feature/js-sdk/releases/tag/react-sdk-v1.4.0">
20
+ <img alt="Release" src="https://img.shields.io/static/v1?label=release&message=v1.4.0&color=blue&style=for-the-badge" />
21
21
  </a>
22
22
  <!-- x-release-please-end -->
23
23
  <br/>
@@ -98,10 +98,16 @@ See the [package.json](./package.json) for the required versions.
98
98
 
99
99
  The `OpenFeatureProvider` is a [React context provider](https://react.dev/reference/react/createContext#provider) which represents a scope for feature flag evaluations within a React application.
100
100
  It binds an OpenFeature client to all evaluations within child components, and allows the use of evaluation hooks.
101
- The example below shows how to use the `OpenFeatureProvider` with OpenFeature's `InMemoryProvider`.
101
+ The example below shows how to use the `OpenFeatureProvider` with OpenFeature's `TypedInMemoryProvider`.
102
102
 
103
103
  ```tsx
104
- import { EvaluationContext, OpenFeatureProvider, useFlag, OpenFeature, InMemoryProvider } from '@openfeature/react-sdk';
104
+ import {
105
+ EvaluationContext,
106
+ OpenFeatureProvider,
107
+ useFlag,
108
+ OpenFeature,
109
+ TypedInMemoryProvider,
110
+ } from '@openfeature/react-sdk';
105
111
 
106
112
  const flagConfig = {
107
113
  'new-message': {
@@ -118,11 +124,11 @@ const flagConfig = {
118
124
  return 'off';
119
125
  },
120
126
  },
121
- };
127
+ } as const;
122
128
 
123
129
  // Instantiate and set our provider (be sure this only happens once)!
124
130
  // Note: there's no need to await its initialization, the React SDK handles re-rendering and suspense for you!
125
- OpenFeature.setProvider(new InMemoryProvider(flagConfig));
131
+ OpenFeature.setProvider(new TypedInMemoryProvider(flagConfig));
126
132
 
127
133
  // Enclose your content in the configured provider
128
134
  function App() {
@@ -251,6 +257,22 @@ This is analogous to:
251
257
  OpenFeature.getClient('my-domain');
252
258
  ```
253
259
 
260
+ Alternatively, a pre-configured `Client` instance can be passed directly via the `client` prop:
261
+
262
+ ```tsx
263
+ const client = OpenFeature.getClient('my-domain');
264
+
265
+ function App() {
266
+ return (
267
+ <OpenFeatureProvider client={client}>
268
+ <Page></Page>
269
+ </OpenFeatureProvider>
270
+ );
271
+ }
272
+ ```
273
+
274
+ The `domain` and `client` props are mutually exclusive.
275
+
254
276
  For more information about `domains`, refer to the [web SDK](https://github.com/open-feature/js-sdk/blob/main/packages/web/README.md).
255
277
 
256
278
  #### Re-rendering with Context Changes
@@ -369,6 +391,10 @@ React's lifecycle can result in flags being evaluated multiple times as a user i
369
391
  If you are using an OpenFeature hook for telemetry, this can result in inflated evaluation metrics.
370
392
  The [OpenFeature debounce hook](https://github.com/open-feature/js-sdk-contrib/tree/main/libs/hooks/debounce) can help to reduce the amount of redundant evaluations reported to your observability platform by limiting the frequency at which evaluation metrics are reported.
371
393
 
394
+ #### Type-Safe Flag Keys
395
+
396
+ For enhanced type safety and autocompletion, you can override flag key types using TypeScript module augmentation. See the [`@openfeature/core` README](../shared/README.md#type-safe-flag-keys) for details.
397
+
372
398
  ### Testing
373
399
 
374
400
  The React SDK includes a built-in context provider for testing.
package/dist/cjs/index.js CHANGED
@@ -485,12 +485,37 @@ function FeatureFlag({
485
485
  return /* @__PURE__ */ import_react7.default.createElement(import_react7.default.Fragment, null, fallbackNode);
486
486
  }
487
487
 
488
+ // ../shared/src/client/framework-metadata.ts
489
+ function withFrameworkMetadata(client, framework) {
490
+ return new Proxy(client, {
491
+ get(target, property, receiver) {
492
+ var _a;
493
+ if (property === "metadata") {
494
+ return __spreadProps(__spreadValues({}, (_a = Reflect.get(target, property, receiver)) != null ? _a : {}), {
495
+ framework
496
+ });
497
+ }
498
+ const value = Reflect.get(target, property, receiver);
499
+ if (typeof value !== "function") {
500
+ return value;
501
+ }
502
+ return (...args) => {
503
+ const result = value.apply(receiver, args);
504
+ return result === target ? receiver : result;
505
+ };
506
+ }
507
+ });
508
+ }
509
+
488
510
  // src/provider/provider.tsx
489
511
  var import_web_sdk6 = require("@openfeature/web-sdk");
490
512
  var React6 = __toESM(require("react"));
491
513
  function OpenFeatureProvider(_a) {
492
514
  var _b = _a, { client, domain, children } = _b, options = __objRest(_b, ["client", "domain", "children"]);
493
- const stableClient = React6.useMemo(() => client || import_web_sdk6.OpenFeature.getClient(domain), [client, domain]);
515
+ const stableClient = React6.useMemo(
516
+ () => withFrameworkMetadata(client || import_web_sdk6.OpenFeature.getClient(domain), "react"),
517
+ [client, domain]
518
+ );
494
519
  return /* @__PURE__ */ React6.createElement(Context.Provider, { value: { client: stableClient, options } }, children);
495
520
  }
496
521
 
@@ -512,19 +537,22 @@ var import_web_sdk8 = require("@openfeature/web-sdk");
512
537
  var import_react8 = __toESM(require("react"));
513
538
  var TEST_VARIANT = "test-variant";
514
539
  var TEST_PROVIDER = "test-provider";
515
- var TestProvider = class extends import_web_sdk8.InMemoryProvider {
540
+ var TestProvider = class extends import_web_sdk8.TypedInMemoryProvider {
516
541
  constructor(flagValueMap, delay = 0) {
517
- const flagConfig = Object.entries(flagValueMap).reduce((acc, flag) => {
518
- return __spreadProps(__spreadValues({}, acc), {
519
- [flag[0]]: {
520
- variants: {
521
- [TEST_VARIANT]: flag[1]
522
- },
523
- defaultVariant: TEST_VARIANT,
524
- disabled: false
525
- }
526
- });
527
- }, {});
542
+ const flagConfig = Object.entries(flagValueMap).reduce(
543
+ (acc, flag) => {
544
+ return __spreadProps(__spreadValues({}, acc), {
545
+ [flag[0]]: {
546
+ variants: {
547
+ [TEST_VARIANT]: flag[1]
548
+ },
549
+ defaultVariant: TEST_VARIANT,
550
+ disabled: false
551
+ }
552
+ });
553
+ },
554
+ {}
555
+ );
528
556
  super(flagConfig);
529
557
  this.delay = delay;
530
558
  // initially make this undefined, we still set it if a delay is specified
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/index.ts", "../../src/declarative/FeatureFlag.tsx", "../../src/evaluation/use-feature-flag.ts", "../../src/internal/context.ts", "../../src/internal/is-equal.ts", "../../src/internal/options.ts", "../../src/internal/suspense.ts", "../../src/internal/use.ts", "../../src/provider/use-open-feature-client.ts", "../../src/internal/errors.ts", "../../src/provider/use-open-feature-client-status.ts", "../../src/provider/use-open-feature-provider.ts", "../../src/internal/hook-flag-query.ts", "../../src/provider/provider.tsx", "../../src/provider/use-when-provider-ready.ts", "../../src/provider/test-provider.tsx", "../../src/context/use-context-mutator.ts", "../../src/tracking/use-track.ts"],
4
- "sourcesContent": ["export * from './declarative';\nexport * from './evaluation';\nexport * from './query';\nexport * from './provider';\nexport * from './context';\nexport * from './tracking';\nexport * from './options';\n// re-export the web-sdk so consumers can access that API from the react-sdk\nexport * from '@openfeature/web-sdk';\n", "import React from 'react';\nimport { useFlag } from '../evaluation';\nimport type { FlagQuery } from '../query';\nimport type { FlagValue, EvaluationDetails } from '@openfeature/core';\nimport { isEqual } from '../internal';\nimport type { ReactFlagEvaluationOptions } from '../options';\n\n/**\n * Default predicate function that checks if the expected value equals the actual flag value.\n * @param {T} expected The expected value to match against\n * @param {EvaluationDetails<T>} actual The evaluation details containing the actual flag value\n * @returns {boolean} true if the values match, false otherwise\n */\nfunction equals<T extends FlagValue>(expected: T, actual: EvaluationDetails<T>): boolean {\n return isEqual(expected, actual.value);\n}\n\n/**\n * Props for the FeatureFlag component that conditionally renders content based on feature flag state.\n * @interface FeatureFlagProps\n */\ninterface FeatureFlagProps<T extends FlagValue = FlagValue> {\n /**\n * The key of the feature flag to evaluate.\n */\n flagKey: string;\n\n /**\n * Optional predicate function for custom matching logic.\n * If provided, this function will be used instead of the default equality check.\n * @param matchValue The value to match (matchValue prop)\n * @param details The evaluation details\n * @returns true if the condition is met, false otherwise\n */\n predicate?: (matchValue: T | undefined, details: EvaluationDetails<T>) => boolean;\n\n /**\n * Content to render when the feature flag condition is met.\n * Can be a React node or a function that receives flag query details and returns a React node.\n */\n children: React.ReactNode | ((details: FlagQuery<T>) => React.ReactNode);\n\n /**\n * Optional content to render when the feature flag condition is not met.\n * Can be a React node or a function that receives evaluation details and returns a React node.\n */\n fallback?: React.ReactNode | ((details: EvaluationDetails<T>) => React.ReactNode);\n\n /**\n * Flag evaluation options that will be passed to useFlag hook.\n */\n evaluationOptions?: ReactFlagEvaluationOptions;\n}\n\n/**\n * Configuration for matching flag values.\n * For boolean flags, `match` is optional (defaults to checking truthiness).\n * For non-boolean flags (string, number, object), `match` is required to determine when to render.\n */\ntype FeatureFlagMatchConfig<T extends FlagValue> = {\n /**\n * Default value to use when the feature flag is not found.\n */\n defaultValue: T;\n} & (T extends boolean\n ? {\n /**\n * Optional value to match against the feature flag value.\n */\n matchValue?: T | undefined;\n }\n : {\n /**\n * Value to match against the feature flag value.\n * Required for non-boolean flags to determine when children should render.\n * By default, strict equality is used for comparison.\n */\n matchValue: T;\n });\n\ntype FeatureFlagComponentProps<T extends FlagValue> = FeatureFlagProps<T> & FeatureFlagMatchConfig<T>;\n\n/**\n * @experimental This API is experimental, and is subject to change.\n * FeatureFlag component that conditionally renders its children based on the evaluation of a feature flag.\n * @param {FeatureFlagComponentProps} props The properties for the FeatureFlag component.\n * @returns {React.ReactElement | null} The rendered component or null if the feature is not enabled.\n */\nexport function FeatureFlag<T extends FlagValue = FlagValue>({\n flagKey,\n matchValue,\n predicate,\n defaultValue,\n children,\n evaluationOptions = {},\n fallback = null,\n}: FeatureFlagComponentProps<T>): React.ReactElement | null {\n const details = useFlag(flagKey, defaultValue, {\n updateOnContextChanged: true,\n ...evaluationOptions,\n });\n\n // If the flag evaluation failed, we render the fallback\n if (details.reason === 'ERROR') {\n const fallbackNode: React.ReactNode =\n typeof fallback === 'function' ? fallback(details.details as EvaluationDetails<T>) : fallback;\n return <>{fallbackNode}</>;\n }\n\n // Use custom predicate if provided, otherwise use default matching logic\n let shouldRender = false;\n if (predicate) {\n shouldRender = predicate(matchValue as T, details.details as EvaluationDetails<T>);\n } else if (matchValue !== undefined) {\n // Default behavior: check if match value equals flag value\n shouldRender = equals(matchValue, details.details as EvaluationDetails<T>);\n } else if (details.type === 'boolean') {\n // If no match value is provided, render if flag is truthy\n shouldRender = Boolean(details.value);\n } else {\n shouldRender = false;\n }\n\n if (shouldRender) {\n const childNode: React.ReactNode = typeof children === 'function' ? children(details as FlagQuery<T>) : children;\n return <>{childNode}</>;\n }\n\n const fallbackNode: React.ReactNode =\n typeof fallback === 'function' ? fallback(details.details as EvaluationDetails<T>) : fallback;\n return <>{fallbackNode}</>;\n}\n", "import type {\n Client,\n ClientProviderEvents,\n EvaluationDetails,\n EventHandler,\n FlagEvaluationOptions,\n FlagValue,\n JsonValue,\n} from '@openfeature/web-sdk';\nimport { ProviderEvents, ProviderStatus } from '@openfeature/web-sdk';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport {\n DEFAULT_OPTIONS,\n isEqual,\n normalizeOptions,\n suspendUntilInitialized,\n suspendUntilReconciled,\n useProviderOptions,\n} from '../internal';\nimport type { ReactFlagEvaluationNoSuspenseOptions, ReactFlagEvaluationOptions } from '../options';\nimport { useOpenFeatureClient } from '../provider/use-open-feature-client';\nimport { useOpenFeatureClientStatus } from '../provider/use-open-feature-client-status';\nimport { useOpenFeatureProvider } from '../provider/use-open-feature-provider';\nimport type { FlagQuery } from '../query';\nimport { HookFlagQuery } from '../internal/hook-flag-query';\n\n// This type is a bit wild-looking, but I think we need it.\n// We have to use the conditional, because otherwise useFlag('key', false) would return false, not boolean (too constrained).\n// We have a duplicate for the hook return below, this one is just used for casting because the name isn't as clear\ntype ConstrainedFlagQuery<T> = FlagQuery<\n T extends boolean\n ? boolean\n : T extends number\n ? number\n : T extends string\n ? string\n : T extends JsonValue\n ? T\n : JsonValue\n>;\n\n/**\n * Evaluates a feature flag generically, returning an react-flavored queryable object.\n * The resolver method to use is based on the type of the defaultValue.\n * For type-specific hooks, use {@link useBooleanFlagValue}, {@link useBooleanFlagDetails} and equivalents.\n * By default, components will re-render when the flag value changes.\n * @param {string} flagKey the flag identifier\n * @template {FlagValue} T A optional generic argument constraining the default.\n * @param {T} defaultValue the default value; used to determine what resolved type should be used.\n * @param {ReactFlagEvaluationOptions} options for this evaluation\n * @returns { FlagQuery } a queryable object containing useful information about the flag.\n */\nexport function useFlag<T extends FlagValue = FlagValue>(\n flagKey: string,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): FlagQuery<\n T extends boolean\n ? boolean\n : T extends number\n ? number\n : T extends string\n ? string\n : T extends JsonValue\n ? T\n : JsonValue\n> {\n // use the default value to determine the resolver to call\n const query =\n typeof defaultValue === 'boolean'\n ? new HookFlagQuery<boolean>(useBooleanFlagDetails(flagKey, defaultValue, options))\n : typeof defaultValue === 'number'\n ? new HookFlagQuery<number>(useNumberFlagDetails(flagKey, defaultValue, options))\n : typeof defaultValue === 'string'\n ? new HookFlagQuery<string>(useStringFlagDetails(flagKey, defaultValue, options))\n : new HookFlagQuery<JsonValue>(useObjectFlagDetails(flagKey, defaultValue, options));\n // TS sees this as HookFlagQuery<JsonValue>, because the compiler isn't aware of the `typeof` checks above.\n return query as unknown as ConstrainedFlagQuery<T>;\n}\n\n// alias to the return value of useFlag, used to keep useSuspenseFlag consistent\ntype UseFlagReturn<T extends FlagValue> = ReturnType<typeof useFlag<T>>;\n\n/**\n * Equivalent to {@link useFlag} with `options: { suspend: true }`\n * @experimental Suspense is an experimental feature subject to change in future versions.\n * @param {string} flagKey the flag identifier\n * @template {FlagValue} T A optional generic argument constraining the default.\n * @param {T} defaultValue the default value; used to determine what resolved type should be used.\n * @param {ReactFlagEvaluationNoSuspenseOptions} options for this evaluation\n * @returns { UseFlagReturn<T> } a queryable object containing useful information about the flag.\n */\nexport function useSuspenseFlag<T extends FlagValue = FlagValue>(\n flagKey: string,\n defaultValue: T,\n options?: ReactFlagEvaluationNoSuspenseOptions,\n): UseFlagReturn<T> {\n return useFlag(flagKey, defaultValue, { ...options, suspendUntilReady: true, suspendWhileReconciling: true });\n}\n\n/**\n * Evaluates a feature flag, returning a boolean.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {string} flagKey the flag identifier\n * @param {boolean} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { boolean} a EvaluationDetails object for this evaluation\n */\nexport function useBooleanFlagValue(\n flagKey: string,\n defaultValue: boolean,\n options?: ReactFlagEvaluationOptions,\n): boolean {\n return useBooleanFlagDetails(flagKey, defaultValue, options).value;\n}\n\n/**\n * Evaluates a feature flag, returning evaluation details.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {string} flagKey the flag identifier\n * @param {boolean} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { EvaluationDetails<boolean>} a EvaluationDetails object for this evaluation\n */\nexport function useBooleanFlagDetails(\n flagKey: string,\n defaultValue: boolean,\n options?: ReactFlagEvaluationOptions,\n): EvaluationDetails<boolean> {\n return attachHandlersAndResolve(\n flagKey,\n defaultValue,\n (client) => {\n return client.getBooleanDetails;\n },\n options,\n );\n}\n\n/**\n * Evaluates a feature flag, returning a string.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {string} flagKey the flag identifier\n * @template {string} [T=string] A optional generic argument constraining the string\n * @param {T} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { boolean} a EvaluationDetails object for this evaluation\n */\nexport function useStringFlagValue<T extends string = string>(\n flagKey: string,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): string {\n return useStringFlagDetails(flagKey, defaultValue, options).value;\n}\n\n/**\n * Evaluates a feature flag, returning evaluation details.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {string} flagKey the flag identifier\n * @template {string} [T=string] A optional generic argument constraining the string\n * @param {T} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { EvaluationDetails<string>} a EvaluationDetails object for this evaluation\n */\nexport function useStringFlagDetails<T extends string = string>(\n flagKey: string,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): EvaluationDetails<string> {\n return attachHandlersAndResolve(\n flagKey,\n defaultValue,\n (client) => {\n return client.getStringDetails<T>;\n },\n options,\n );\n}\n\n/**\n * Evaluates a feature flag, returning a number.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {string} flagKey the flag identifier\n * @template {number} [T=number] A optional generic argument constraining the number\n * @param {T} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { boolean} a EvaluationDetails object for this evaluation\n */\nexport function useNumberFlagValue<T extends number = number>(\n flagKey: string,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): number {\n return useNumberFlagDetails(flagKey, defaultValue, options).value;\n}\n\n/**\n * Evaluates a feature flag, returning evaluation details.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {string} flagKey the flag identifier\n * @template {number} [T=number] A optional generic argument constraining the number\n * @param {T} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { EvaluationDetails<number>} a EvaluationDetails object for this evaluation\n */\nexport function useNumberFlagDetails<T extends number = number>(\n flagKey: string,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): EvaluationDetails<number> {\n return attachHandlersAndResolve(\n flagKey,\n defaultValue,\n (client) => {\n return client.getNumberDetails<T>;\n },\n options,\n );\n}\n\n/**\n * Evaluates a feature flag, returning an object.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {string} flagKey the flag identifier\n * @template {JsonValue} [T=JsonValue] A optional generic argument describing the structure\n * @param {T} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { boolean} a EvaluationDetails object for this evaluation\n */\nexport function useObjectFlagValue<T extends JsonValue = JsonValue>(\n flagKey: string,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): T {\n return useObjectFlagDetails<T>(flagKey, defaultValue, options).value;\n}\n\n/**\n * Evaluates a feature flag, returning evaluation details.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {string} flagKey the flag identifier\n * @param {T} defaultValue the default value\n * @template {JsonValue} [T=JsonValue] A optional generic argument describing the structure\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { EvaluationDetails<T>} a EvaluationDetails object for this evaluation\n */\nexport function useObjectFlagDetails<T extends JsonValue = JsonValue>(\n flagKey: string,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): EvaluationDetails<T> {\n return attachHandlersAndResolve(\n flagKey,\n defaultValue,\n (client) => {\n return client.getObjectDetails<T>;\n },\n options,\n );\n}\n\n// determines if a flag should be re-evaluated based on a list of changed flags\nfunction shouldEvaluateFlag(flagKey: string, flagsChanged?: string[]): boolean {\n // if flagsChange is missing entirely, we don't know what to re-render\n return !flagsChanged || flagsChanged.includes(flagKey);\n}\n\nfunction attachHandlersAndResolve<T extends FlagValue>(\n flagKey: string,\n defaultValue: T,\n resolver: (\n client: Client,\n ) => (flagKey: string, defaultValue: T, options?: FlagEvaluationOptions) => EvaluationDetails<T>,\n options?: ReactFlagEvaluationOptions,\n): EvaluationDetails<T> {\n // highest priority > evaluation hook options > provider options > default options > lowest priority\n const defaultedOptions = { ...DEFAULT_OPTIONS, ...useProviderOptions(), ...normalizeOptions(options) };\n const client = useOpenFeatureClient();\n const status = useOpenFeatureClientStatus();\n const provider = useOpenFeatureProvider();\n const isFirstRender = useRef(true);\n\n if (defaultedOptions.suspendUntilReady && status === ProviderStatus.NOT_READY) {\n suspendUntilInitialized(provider, client);\n }\n\n if (defaultedOptions.suspendWhileReconciling && status === ProviderStatus.RECONCILING) {\n suspendUntilReconciled(client);\n }\n\n const [evaluationDetails, setEvaluationDetails] = useState<EvaluationDetails<T>>(() =>\n resolver(client).call(client, flagKey, defaultValue, options),\n );\n\n // Re-evaluate when dependencies change (handles prop changes like flagKey), or if during a re-render, we have detected a change in the evaluated value\n useEffect(() => {\n if (isFirstRender.current) {\n isFirstRender.current = false;\n return;\n }\n\n const newDetails = resolver(client).call(client, flagKey, defaultValue, options);\n if (!isEqual(newDetails, evaluationDetails)) {\n setEvaluationDetails(newDetails);\n }\n }, [client, flagKey, defaultValue, options, resolver, evaluationDetails]);\n\n // Maintain a mutable reference to the evaluation details to have a up-to-date reference in the handlers.\n const evaluationDetailsRef = useRef<EvaluationDetails<T>>(evaluationDetails);\n useEffect(() => {\n evaluationDetailsRef.current = evaluationDetails;\n }, [evaluationDetails]);\n\n const updateEvaluationDetailsCallback = useCallback(() => {\n const updatedEvaluationDetails = resolver(client).call(client, flagKey, defaultValue, options);\n\n /**\n * Avoid re-rendering if the evaluation details haven't changed.\n */\n if (!isEqual(updatedEvaluationDetails, evaluationDetailsRef.current)) {\n setEvaluationDetails(updatedEvaluationDetails);\n }\n }, [client, flagKey, defaultValue, options, resolver]);\n\n const configurationChangeCallback = useCallback<EventHandler<ClientProviderEvents.ConfigurationChanged>>(\n (eventDetails) => {\n if (shouldEvaluateFlag(flagKey, eventDetails?.flagsChanged)) {\n updateEvaluationDetailsCallback();\n }\n },\n [flagKey, updateEvaluationDetailsCallback],\n );\n\n useEffect(() => {\n const controller = new AbortController();\n // Always register the Ready handler to catch provider initialization\n // even if current status is already READY (e.g., from a NoOp provider)\n client.addHandler(ProviderEvents.Ready, updateEvaluationDetailsCallback, { signal: controller.signal });\n\n if (defaultedOptions.updateOnContextChanged) {\n // update when the context changes\n client.addHandler(ProviderEvents.ContextChanged, updateEvaluationDetailsCallback, { signal: controller.signal });\n }\n\n if (defaultedOptions.updateOnConfigurationChanged) {\n // update when the provider configuration changes\n client.addHandler(ProviderEvents.ConfigurationChanged, configurationChangeCallback, {\n signal: controller.signal,\n });\n }\n return () => {\n // cleanup the handlers\n controller.abort();\n };\n }, [\n client,\n defaultedOptions.updateOnContextChanged,\n defaultedOptions.updateOnConfigurationChanged,\n updateEvaluationDetailsCallback,\n configurationChangeCallback,\n ]);\n\n return evaluationDetails;\n}\n", "import type { Client } from '@openfeature/web-sdk';\nimport React from 'react';\nimport type { NormalizedOptions, ReactFlagEvaluationOptions } from '../options';\nimport { normalizeOptions } from '.';\n\n/**\n * The underlying React context.\n *\n * **DO NOT EXPORT PUBLICLY**\n * @internal\n */\nexport const Context = React.createContext<{ client: Client; options: ReactFlagEvaluationOptions } | undefined>(\n undefined,\n);\n\n/**\n * Get a normalized copy of the options used for this OpenFeatureProvider, see {@link normalizeOptions}.\n *\n * **DO NOT EXPORT PUBLICLY**\n * @internal\n * @returns {NormalizedOptions} normalized options the defaulted options, not defaulted or normalized.\n */\nexport function useProviderOptions(): NormalizedOptions {\n const { options } = React.useContext(Context) || {};\n return normalizeOptions(options);\n}\n", "/**\n * Deeply compare two values to determine if they are equal.\n * Supports primitives and serializable objects.\n *\n * Note: Does not handle Date, RegExp, Map, Set, or circular references.\n * Suitable for comparing EvaluationDetails and other JSON-serializable data.\n * @param {unknown} value First value to compare\n * @param {unknown} other Second value to compare\n * @returns {boolean} True if the values are equal\n */\nexport function isEqual(value: unknown, other: unknown): boolean {\n if (value === other) {\n return true;\n }\n\n if (typeof value !== typeof other) {\n return false;\n }\n\n if (typeof value === 'object' && value !== null && typeof other === 'object' && other !== null) {\n const valueKeys = Object.keys(value);\n const otherKeys = Object.keys(other);\n\n if (valueKeys.length !== otherKeys.length) {\n return false;\n }\n\n for (const key of valueKeys) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (!isEqual((value as any)[key], (other as any)[key])) {\n return false;\n }\n }\n\n return true;\n }\n\n return false;\n}\n", "import type { ReactFlagEvaluationOptions, NormalizedOptions } from '../options';\n\n/**\n * Default options.\n * DO NOT EXPORT PUBLICLY\n * @internal\n */\nexport const DEFAULT_OPTIONS: ReactFlagEvaluationOptions = {\n updateOnContextChanged: true,\n updateOnConfigurationChanged: true,\n suspendUntilReady: false,\n suspendWhileReconciling: false,\n};\n\n/**\n * Returns normalization options (all `undefined` fields removed, and `suspend` decomposed to `suspendUntilReady` and `suspendWhileReconciling`).\n * DO NOT EXPORT PUBLICLY\n * @internal\n * @param {ReactFlagEvaluationOptions} options options to normalize\n * @returns {NormalizedOptions} normalized options\n */\nexport const normalizeOptions: (options?: ReactFlagEvaluationOptions) => NormalizedOptions = (\n options: ReactFlagEvaluationOptions = {},\n) => {\n const updateOnContextChanged = options.updateOnContextChanged;\n const updateOnConfigurationChanged = options.updateOnConfigurationChanged;\n\n // fall-back the suspense options to the catch-all `suspend` property\n const suspendUntilReady = 'suspendUntilReady' in options ? options.suspendUntilReady : options.suspend;\n const suspendWhileReconciling =\n 'suspendWhileReconciling' in options ? options.suspendWhileReconciling : options.suspend;\n\n return {\n // only return these if properly set (no undefined to allow overriding with spread)\n ...(typeof suspendUntilReady === 'boolean' && { suspendUntilReady }),\n ...(typeof suspendWhileReconciling === 'boolean' && { suspendWhileReconciling }),\n ...(typeof updateOnContextChanged === 'boolean' && { updateOnContextChanged }),\n ...(typeof updateOnConfigurationChanged === 'boolean' && { updateOnConfigurationChanged }),\n };\n};\n", "import type { Client, Provider } from '@openfeature/web-sdk';\nimport { NOOP_PROVIDER, ProviderEvents } from '@openfeature/web-sdk';\nimport { use } from './use';\n\n/**\n * A weak map is used to store the global suspense status for each provider. It's\n * important for this to be global to avoid rerender loops. Using useRef won't\n * work because the value isn't preserved when a promise is thrown in a component,\n * which is how suspense operates.\n */\nconst globalProviderSuspenseStatus = new WeakMap<Provider, Promise<unknown>>();\n\n/**\n * Suspends until the client is ready to evaluate feature flags.\n *\n * **DO NOT EXPORT PUBLICLY**\n * @internal\n * @param {Provider} provider the provider to suspend for\n * @param {Client} client the client to check for readiness\n */\nexport function suspendUntilInitialized(provider: Provider, client: Client) {\n const statusPromiseRef = globalProviderSuspenseStatus.get(provider);\n if (!statusPromiseRef) {\n // Noop provider is never ready, so we resolve immediately\n const statusPromise = provider !== NOOP_PROVIDER ? isProviderReady(client) : Promise.resolve();\n globalProviderSuspenseStatus.set(provider, statusPromise);\n // Use will throw the promise and React will trigger a rerender when it's resolved\n use(statusPromise);\n } else {\n // Reuse the existing promise, use won't rethrow if the promise has settled.\n use(statusPromiseRef);\n }\n}\n\n/**\n * Suspends until the provider has finished reconciling.\n *\n * **DO NOT EXPORT PUBLICLY**\n * @internal\n * @param {Client} client the client to check for readiness\n */\nexport function suspendUntilReconciled(client: Client) {\n use(isProviderReady(client));\n}\n\nasync function isProviderReady(client: Client) {\n const controller = new AbortController();\n try {\n return await new Promise((resolve, reject) => {\n client.addHandler(ProviderEvents.Ready, resolve, { signal: controller.signal });\n client.addHandler(ProviderEvents.Error, reject, { signal: controller.signal });\n });\n } finally {\n controller.abort();\n }\n}\n", "/// <reference types=\"react/experimental\" />\n// This function is adopted from https://github.com/vercel/swr\nimport React from 'react';\n\n/**\n * Extends a Promise-like value to include status tracking.\n * The extra properties are used to manage the lifecycle of the Promise, indicating its current state.\n * More information can be found in the React RFE for the use hook.\n * @see https://github.com/reactjs/rfcs/pull/229\n */\nexport type UsePromise<T> = Promise<T> & {\n status?: 'pending' | 'fulfilled' | 'rejected';\n value?: T;\n reason?: unknown;\n};\n\n/**\n * React.use is a React API that lets you read the value of a resource like a Promise or context.\n * It was officially added in React 19, so needs to be polyfilled to support older React versions.\n * @param {UsePromise} thenable A thenable object that represents a Promise-like value.\n * @returns {unknown} The resolved value of the thenable or throws if it's still pending or rejected.\n */\nexport const use =\n React.use ||\n // This extra generic is to avoid TypeScript mixing up the generic and JSX syntax\n // and emitting an error.\n // We assume that this is only for the `use(thenable)` case, not `use(context)`.\n // https://github.com/facebook/react/blob/aed00dacfb79d17c53218404c52b1c7aa59c4a89/packages/react-server/src/ReactFizzThenable.js#L45\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n (<T, _>(thenable: UsePromise<T>): T => {\n switch (thenable.status) {\n case 'pending':\n throw thenable;\n case 'fulfilled':\n return thenable.value as T;\n case 'rejected':\n throw thenable.reason;\n default:\n thenable.status = 'pending';\n thenable.then(\n (v) => {\n thenable.status = 'fulfilled';\n thenable.value = v;\n },\n (e) => {\n thenable.status = 'rejected';\n thenable.reason = e;\n },\n );\n throw thenable;\n }\n });\n", "import React from 'react';\nimport { Context } from '../internal';\nimport { type Client } from '@openfeature/web-sdk';\nimport { MissingContextError } from '../internal/errors';\n\n/**\n * Get the {@link Client} instance for this OpenFeatureProvider context.\n * Note that the provider to which this is bound is determined by the OpenFeatureProvider's domain.\n * @returns {Client} client for this scope\n */\nexport function useOpenFeatureClient(): Client {\n const { client } = React.useContext(Context) || {};\n\n if (!client) {\n throw new MissingContextError('No OpenFeature client available');\n }\n\n return client;\n}\n", "const context = 'Components using OpenFeature must be wrapped with an <OpenFeatureProvider>.';\nconst tip =\n 'If you are seeing this in a test, see: https://openfeature.dev/docs/reference/technologies/client/web/react#testing';\n\nexport class MissingContextError extends Error {\n constructor(reason: string) {\n super(`${reason}: ${context} ${tip}`);\n this.name = 'MissingContextError';\n }\n}\n", "import { useEffect, useState } from 'react';\nimport { useOpenFeatureClient } from './use-open-feature-client';\nimport type { ProviderStatus } from '@openfeature/web-sdk';\nimport { ProviderEvents } from '@openfeature/web-sdk';\n\n/**\n * Get the {@link ProviderStatus} for the OpenFeatureClient.\n * Reacts to changes in provider status.\n * @returns {ProviderStatus} status of the client for this scope\n */\nexport function useOpenFeatureClientStatus(): ProviderStatus {\n const client = useOpenFeatureClient();\n const [status, setStatus] = useState<ProviderStatus>(client.providerStatus);\n\n useEffect(() => {\n const controller = new AbortController();\n const updateStatus = () => setStatus(client.providerStatus);\n client.addHandler(ProviderEvents.ConfigurationChanged, updateStatus, { signal: controller.signal });\n client.addHandler(ProviderEvents.ContextChanged, updateStatus, { signal: controller.signal });\n client.addHandler(ProviderEvents.Error, updateStatus, { signal: controller.signal });\n client.addHandler(ProviderEvents.Ready, updateStatus, { signal: controller.signal });\n client.addHandler(ProviderEvents.Stale, updateStatus, { signal: controller.signal });\n client.addHandler(ProviderEvents.Reconciling, updateStatus, { signal: controller.signal });\n return () => {\n controller.abort();\n };\n }, [client]);\n\n return status;\n}\n", "import React from 'react';\nimport { Context } from '../internal';\nimport { OpenFeature } from '@openfeature/web-sdk';\nimport type { Provider } from '@openfeature/web-sdk';\nimport { MissingContextError } from '../internal/errors';\n\n/**\n * Get the {@link Provider} bound to the domain specified in the OpenFeatureProvider context.\n * Note that it isn't recommended to interact with the provider directly, but rather through\n * an OpenFeature client.\n * @returns {Provider} provider for this scope\n */\nexport function useOpenFeatureProvider(): Provider {\n const openFeatureContext = React.useContext(Context);\n\n if (!openFeatureContext) {\n throw new MissingContextError('No OpenFeature context available');\n }\n\n return OpenFeature.getProvider(openFeatureContext.client.metadata.domain);\n}\n", "import type { EvaluationDetails, FlagValue } from '@openfeature/web-sdk';\nimport { StandardResolutionReasons } from '@openfeature/web-sdk';\nimport type { FlagQuery } from '../query';\n\n// FlagQuery implementation, do not export\nexport class HookFlagQuery<T extends FlagValue = FlagValue> implements FlagQuery {\n constructor(private _details: EvaluationDetails<T>) {}\n\n get details() {\n return this._details;\n }\n\n get value() {\n return this._details?.value;\n }\n\n get variant() {\n return this._details.variant;\n }\n\n get flagMetadata() {\n return this._details.flagMetadata;\n }\n\n get reason() {\n return this._details.reason;\n }\n\n get isError() {\n return !!this._details?.errorCode || this._details.reason == StandardResolutionReasons.ERROR;\n }\n\n get errorCode() {\n return this._details?.errorCode;\n }\n\n get errorMessage() {\n return this._details?.errorMessage;\n }\n\n get isAuthoritative() {\n return (\n !this.isError &&\n this._details.reason != StandardResolutionReasons.STALE &&\n this._details.reason != StandardResolutionReasons.DISABLED\n );\n }\n\n get type() {\n return typeof this._details.value;\n }\n}\n", "import type { Client } from '@openfeature/web-sdk';\nimport { OpenFeature } from '@openfeature/web-sdk';\nimport * as React from 'react';\nimport type { ReactFlagEvaluationOptions } from '../options';\nimport { Context } from '../internal';\n\ntype ClientOrDomain =\n | {\n /**\n * An identifier which logically binds clients with providers\n * @see OpenFeature.setProvider() and overloads.\n */\n domain?: string;\n client?: never;\n }\n | {\n /**\n * OpenFeature client to use.\n */\n client?: Client;\n domain?: never;\n };\n\ntype ProviderProps = {\n children?: React.ReactNode;\n} & ClientOrDomain &\n ReactFlagEvaluationOptions;\n\n/**\n * Provides a scope for evaluating feature flags by binding a client to all child components.\n * @param {ProviderProps} properties props for the context provider\n * @returns {OpenFeatureProvider} context provider\n */\nexport function OpenFeatureProvider({ client, domain, children, ...options }: ProviderProps) {\n const stableClient = React.useMemo(() => client || OpenFeature.getClient(domain), [client, domain]);\n\n return <Context.Provider value={{ client: stableClient, options }}>{children}</Context.Provider>;\n}\n", "import { ProviderStatus } from '@openfeature/web-sdk';\nimport { useOpenFeatureClient } from './use-open-feature-client';\nimport { useOpenFeatureClientStatus } from './use-open-feature-client-status';\nimport type { ReactFlagEvaluationOptions } from '../options';\nimport { DEFAULT_OPTIONS, useProviderOptions, normalizeOptions, suspendUntilInitialized } from '../internal';\nimport { useOpenFeatureProvider } from './use-open-feature-provider';\n\ntype Options = Pick<ReactFlagEvaluationOptions, 'suspendUntilReady'>;\n\n/**\n * Utility hook that triggers suspense until the provider is {@link ProviderStatus.READY}, without evaluating any flags.\n * Especially useful for React v16/17 \"Legacy Suspense\", in which siblings to suspending components are\n * initially mounted and then hidden (see: https://github.com/reactwg/react-18/discussions/7).\n *\n * NOTE: This hook returns true only when the provider status is {@link ProviderStatus.READY}.\n * For other statuses (ERROR, STALE, FATAL, RECONCILING), use {@link useOpenFeatureClientStatus}.\n * @param {Options} options options for suspense\n * @returns {boolean} boolean indicating if provider is {@link ProviderStatus.READY}, useful if suspense is disabled and you want to handle loaders on your own\n */\nexport function useWhenProviderReady(options?: Options): boolean {\n // highest priority > evaluation hook options > provider options > default options > lowest priority\n const defaultedOptions = { ...DEFAULT_OPTIONS, ...useProviderOptions(), ...normalizeOptions(options) };\n const client = useOpenFeatureClient();\n const status = useOpenFeatureClientStatus();\n const provider = useOpenFeatureProvider();\n\n if (defaultedOptions.suspendUntilReady && status === ProviderStatus.NOT_READY) {\n suspendUntilInitialized(provider, client);\n }\n\n return status === ProviderStatus.READY;\n}\n", "import type { JsonValue, Provider } from '@openfeature/web-sdk';\nimport { InMemoryProvider, NOOP_PROVIDER, OpenFeature } from '@openfeature/web-sdk';\nimport React from 'react';\nimport type { NormalizedOptions } from '../options';\nimport { OpenFeatureProvider } from './provider';\n\ntype FlagValueMap = { [flagKey: string]: JsonValue };\ntype FlagConfig = ConstructorParameters<typeof InMemoryProvider>[0];\ntype TestProviderProps = Omit<React.ComponentProps<typeof OpenFeatureProvider>, 'client'> &\n (\n | {\n provider?: never;\n /**\n * Optional map of flagKeys to flagValues for this OpenFeatureTestProvider context.\n * If not supplied, all flag evaluations will default.\n */\n flagValueMap?: FlagValueMap;\n /**\n * Optional delay for the underlying test provider's readiness and reconciliation.\n * Defaults to 0.\n */\n delayMs?: number;\n }\n | {\n /**\n * An optional partial provider to pass for full control over the flag resolution for this OpenFeatureTestProvider context.\n * Any un-implemented methods or properties will no-op.\n */\n provider?: Partial<Provider>;\n flagValueMap?: never;\n delayMs?: never;\n }\n );\n\nconst TEST_VARIANT = 'test-variant';\nconst TEST_PROVIDER = 'test-provider';\n\n// internal provider which is basically the in-memory provider with a simpler config and some optional fake delays\nclass TestProvider extends InMemoryProvider {\n // initially make this undefined, we still set it if a delay is specified\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore - For maximum compatibility with previous versions, we ignore a possible TS error here,\n // since \"initialize\" was previously defined in superclass.\n // We can safely remove this ts-ignore in a few versions\n initialize: Provider['initialize'] = undefined;\n\n // \"place-holder\" init function which we only assign if want a delay\n private delayedInitialize = async () => {\n await new Promise<void>((resolve) => setTimeout(resolve, this.delay));\n };\n\n constructor(\n flagValueMap: FlagValueMap,\n private delay = 0,\n ) {\n // convert the simple flagValueMap into an in-memory config\n const flagConfig = Object.entries(flagValueMap).reduce((acc: FlagConfig, flag): FlagConfig => {\n return {\n ...acc,\n [flag[0]]: {\n variants: {\n [TEST_VARIANT]: flag[1],\n },\n defaultVariant: TEST_VARIANT,\n disabled: false,\n },\n };\n }, {});\n super(flagConfig);\n // only define and init if there's a non-zero delay specified\n this.initialize = this.delay ? this.delayedInitialize.bind(this) : undefined;\n }\n\n async onContextChange() {\n return new Promise<void>((resolve) => setTimeout(resolve, this.delay));\n }\n}\n\n/**\n * A React Context provider based on the {@link InMemoryProvider}, specifically built for testing.\n * Use this for testing components that use flag evaluation hooks.\n * @param {TestProviderProps} testProviderOptions options for the OpenFeatureTestProvider\n * @returns {OpenFeatureProvider} OpenFeatureTestProvider\n */\nexport function OpenFeatureTestProvider(testProviderOptions: TestProviderProps) {\n const { flagValueMap, provider } = testProviderOptions;\n const effectiveProvider = (\n flagValueMap ? new TestProvider(flagValueMap, testProviderOptions.delayMs) : mixInNoop(provider) || NOOP_PROVIDER\n ) as Provider;\n testProviderOptions.domain\n ? OpenFeature.setProvider(testProviderOptions.domain, effectiveProvider)\n : OpenFeature.setProvider(effectiveProvider);\n\n return (\n <OpenFeatureProvider {...(testProviderOptions as NormalizedOptions)} domain={testProviderOptions.domain}>\n {testProviderOptions.children}\n </OpenFeatureProvider>\n );\n}\n\n// mix in the no-op provider when the partial is passed\nfunction mixInNoop(provider: Partial<Provider> = {}) {\n // fill in any missing methods with no-ops\n for (const prop of Object.getOwnPropertyNames(Object.getPrototypeOf(NOOP_PROVIDER)).filter(\n (prop) => prop !== 'constructor',\n )) {\n const patchedProvider = provider as { [key: string]: keyof Provider };\n if (!Object.getPrototypeOf(patchedProvider)[prop] && !patchedProvider[prop]) {\n patchedProvider[prop] = Object.getPrototypeOf(NOOP_PROVIDER)[prop];\n }\n }\n // fill in the metadata if missing\n if (!provider.metadata || !provider.metadata.name) {\n (provider.metadata as unknown) = { name: TEST_PROVIDER };\n }\n return provider;\n}\n", "import { useCallback, useContext, useEffect, useState } from 'react';\nimport type { EvaluationContext } from '@openfeature/web-sdk';\nimport { OpenFeature } from '@openfeature/web-sdk';\nimport { Context } from '../internal';\n\nexport type ContextMutationOptions = {\n /**\n * Mutate the default context instead of the domain scoped context applied at the `<OpenFeatureProvider/>`.\n * By default, will use the domain set on `<OpenFeatureProvider/>` (or the domain associated with the client set on `<OpenFeatureProvider/>`).\n * See the {@link https://openfeature.dev/docs/reference/technologies/client/web/#manage-evaluation-context-for-domains|documentation} for more information.\n * @default false\n */\n defaultContext?: boolean;\n};\n\nexport type ContextMutation = {\n /**\n * Context-aware function to set the desired context (see: {@link ContextMutationOptions} for details).\n * There's generally no need to await the result of this function; flag evaluation hooks will re-render when the context is updated.\n * This promise never rejects.\n * @param updatedContext New context object or method to generate it from the current context\n * @returns Promise for awaiting the context update\n */\n setContext: (\n updatedContext: EvaluationContext | ((currentContext: EvaluationContext) => EvaluationContext),\n ) => Promise<void>;\n};\n\n/**\n * Get context-aware tracking function(s) for mutating the evaluation context associated with this domain, or the default context if `defaultContext: true`.\n * See the {@link https://openfeature.dev/docs/reference/technologies/client/web/#targeting-and-context|documentation} for more information.\n * @param {ContextMutationOptions} options options for the generated function\n * @returns {ContextMutation} context-aware function(s) to mutate evaluation context\n */\nexport function useContextMutator(options: ContextMutationOptions = { defaultContext: false }): ContextMutation {\n const { client } = useContext(Context) || {};\n const domain = client?.metadata.domain;\n\n // TODO: Replace this warning with a thrown error in a future major release,\n // to match the behavior of `useOpenFeatureProvider` + `useOpenFeatureClient`,\n // when `defaultContext` isn't explicitly set to true.\n const [warned, setWarned] = useState(false);\n useEffect(() => {\n if (options.defaultContext || domain) {\n if (warned) {\n setWarned(false);\n }\n return;\n }\n\n if (!warned) {\n console.warn(\n '[useContextMutator] No domain available from OpenFeature context; are you using <OpenFeatureProvider/>? setContext will mutate the default context, as if `defaultContext: true` were set. This may result in a thrown error in the future.',\n );\n setWarned(true);\n }\n }, [warned]);\n\n const setContext = useCallback(\n async (\n updatedContext: EvaluationContext | ((currentContext: EvaluationContext) => EvaluationContext),\n ): Promise<void> => {\n const previousContext = OpenFeature.getContext(options?.defaultContext ? undefined : domain);\n const resolvedContext = typeof updatedContext === 'function' ? updatedContext(previousContext) : updatedContext;\n\n if (previousContext !== resolvedContext) {\n if (!domain || options?.defaultContext) {\n await OpenFeature.setContext(resolvedContext);\n } else {\n await OpenFeature.setContext(domain, resolvedContext);\n }\n }\n },\n [domain, options?.defaultContext],\n );\n\n return {\n setContext,\n };\n}\n", "import type { Tracking, TrackingEventDetails } from '@openfeature/web-sdk';\nimport { useCallback } from 'react';\nimport { useOpenFeatureClient } from '../provider';\n\nexport type Track = {\n /**\n * Context-aware tracking function for the parent `<OpenFeatureProvider/>`.\n * Track a user action or application state, usually representing a business objective or outcome.\n * @param trackingEventName an identifier for the event\n * @param trackingEventDetails the details of the tracking event\n */\n track: Tracking['track'];\n};\n\n/**\n * Get a context-aware tracking function.\n * @returns {Track} context-aware tracking\n */\nexport function useTrack(): Track {\n const client = useOpenFeatureClient();\n\n const track = useCallback((trackingEventName: string, trackingEventDetails?: TrackingEventDetails) => {\n client.track(trackingEventName, trackingEventDetails);\n }, []);\n\n return {\n track,\n };\n}\n"],
5
- "mappings": "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",
3
+ "sources": ["../../src/index.ts", "../../src/declarative/FeatureFlag.tsx", "../../src/evaluation/use-feature-flag.ts", "../../src/internal/context.ts", "../../src/internal/is-equal.ts", "../../src/internal/options.ts", "../../src/internal/suspense.ts", "../../src/internal/use.ts", "../../src/provider/use-open-feature-client.ts", "../../src/internal/errors.ts", "../../src/provider/use-open-feature-client-status.ts", "../../src/provider/use-open-feature-provider.ts", "../../src/internal/hook-flag-query.ts", "../../../shared/src/client/framework-metadata.ts", "../../src/provider/provider.tsx", "../../src/provider/use-when-provider-ready.ts", "../../src/provider/test-provider.tsx", "../../src/context/use-context-mutator.ts", "../../src/tracking/use-track.ts"],
4
+ "sourcesContent": ["export * from './declarative';\nexport * from './evaluation';\nexport * from './query';\nexport * from './provider';\nexport * from './context';\nexport * from './tracking';\nexport * from './options';\n// re-export the web-sdk so consumers can access that API from the react-sdk\nexport * from '@openfeature/web-sdk';\n", "import React from 'react';\nimport { useFlag } from '../evaluation';\nimport type { FlagQuery } from '../query';\nimport type { FlagValue, EvaluationDetails, ConstrainedFlagKey } from '@openfeature/web-sdk';\nimport { isEqual } from '../internal';\nimport type { ReactFlagEvaluationOptions } from '../options';\n\n/**\n * Default predicate function that checks if the expected value equals the actual flag value.\n * @param {T} expected The expected value to match against\n * @param {EvaluationDetails<T>} actual The evaluation details containing the actual flag value\n * @returns {boolean} true if the values match, false otherwise\n */\nfunction equals<T extends FlagValue>(expected: T, actual: EvaluationDetails<T>): boolean {\n return isEqual(expected, actual.value);\n}\n\n/**\n * Props for the FeatureFlag component that conditionally renders content based on feature flag state.\n * @interface FeatureFlagProps\n */\ninterface FeatureFlagProps<T extends FlagValue = FlagValue> {\n /**\n * The key of the feature flag to evaluate.\n */\n flagKey: ConstrainedFlagKey<T>;\n\n /**\n * Optional predicate function for custom matching logic.\n * If provided, this function will be used instead of the default equality check.\n * @param matchValue The value to match (matchValue prop)\n * @param details The evaluation details\n * @returns true if the condition is met, false otherwise\n */\n predicate?: (matchValue: T | undefined, details: EvaluationDetails<T>) => boolean;\n\n /**\n * Content to render when the feature flag condition is met.\n * Can be a React node or a function that receives flag query details and returns a React node.\n */\n children: React.ReactNode | ((details: FlagQuery<T>) => React.ReactNode);\n\n /**\n * Optional content to render when the feature flag condition is not met.\n * Can be a React node or a function that receives evaluation details and returns a React node.\n */\n fallback?: React.ReactNode | ((details: EvaluationDetails<T>) => React.ReactNode);\n\n /**\n * Flag evaluation options that will be passed to useFlag hook.\n */\n evaluationOptions?: ReactFlagEvaluationOptions;\n}\n\n/**\n * Configuration for matching flag values.\n * For boolean flags, `match` is optional (defaults to checking truthiness).\n * For non-boolean flags (string, number, object), `match` is required to determine when to render.\n */\ntype FeatureFlagMatchConfig<T extends FlagValue> = {\n /**\n * Default value to use when the feature flag is not found.\n */\n defaultValue: T;\n} & (T extends boolean\n ? {\n /**\n * Optional value to match against the feature flag value.\n */\n matchValue?: T | undefined;\n }\n : {\n /**\n * Value to match against the feature flag value.\n * Required for non-boolean flags to determine when children should render.\n * By default, strict equality is used for comparison.\n */\n matchValue: T;\n });\n\ntype FeatureFlagComponentProps<T extends FlagValue> = FeatureFlagProps<T> & FeatureFlagMatchConfig<T>;\n\n/**\n * @experimental This API is experimental, and is subject to change.\n * FeatureFlag component that conditionally renders its children based on the evaluation of a feature flag.\n * @param {FeatureFlagComponentProps} props The properties for the FeatureFlag component.\n * @returns {React.ReactElement | null} The rendered component or null if the feature is not enabled.\n */\nexport function FeatureFlag<T extends FlagValue = FlagValue>({\n flagKey,\n matchValue,\n predicate,\n defaultValue,\n children,\n evaluationOptions = {},\n fallback = null,\n}: FeatureFlagComponentProps<T>): React.ReactElement | null {\n const details = useFlag(flagKey, defaultValue, {\n updateOnContextChanged: true,\n ...evaluationOptions,\n });\n\n // If the flag evaluation failed, we render the fallback\n if (details.reason === 'ERROR') {\n const fallbackNode: React.ReactNode =\n typeof fallback === 'function' ? fallback(details.details as EvaluationDetails<T>) : fallback;\n return <>{fallbackNode}</>;\n }\n\n // Use custom predicate if provided, otherwise use default matching logic\n let shouldRender = false;\n if (predicate) {\n shouldRender = predicate(matchValue as T, details.details as EvaluationDetails<T>);\n } else if (matchValue !== undefined) {\n // Default behavior: check if match value equals flag value\n shouldRender = equals(matchValue, details.details as EvaluationDetails<T>);\n } else if (details.type === 'boolean') {\n // If no match value is provided, render if flag is truthy\n shouldRender = Boolean(details.value);\n } else {\n shouldRender = false;\n }\n\n if (shouldRender) {\n const childNode: React.ReactNode = typeof children === 'function' ? children(details as FlagQuery<T>) : children;\n return <>{childNode}</>;\n }\n\n const fallbackNode: React.ReactNode =\n typeof fallback === 'function' ? fallback(details.details as EvaluationDetails<T>) : fallback;\n return <>{fallbackNode}</>;\n}\n", "import type {\n BooleanFlagKey,\n Client,\n ClientProviderEvents,\n ConstrainedFlagKey,\n EvaluationDetails,\n EventHandler,\n FlagEvaluationOptions,\n FlagValue,\n JsonValue,\n NumberFlagKey,\n ObjectFlagKey,\n StringFlagKey,\n} from '@openfeature/web-sdk';\nimport { ProviderEvents, ProviderStatus } from '@openfeature/web-sdk';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport {\n DEFAULT_OPTIONS,\n isEqual,\n normalizeOptions,\n suspendUntilInitialized,\n suspendUntilReconciled,\n useProviderOptions,\n} from '../internal';\nimport type { ReactFlagEvaluationNoSuspenseOptions, ReactFlagEvaluationOptions } from '../options';\nimport { useOpenFeatureClient } from '../provider/use-open-feature-client';\nimport { useOpenFeatureClientStatus } from '../provider/use-open-feature-client-status';\nimport { useOpenFeatureProvider } from '../provider/use-open-feature-provider';\nimport type { FlagQuery } from '../query';\nimport { HookFlagQuery } from '../internal/hook-flag-query';\n\n// This type is a bit wild-looking, but I think we need it.\n// We have to use the conditional, because otherwise useFlag('key', false) would return false, not boolean (too constrained).\n// We have a duplicate for the hook return below, this one is just used for casting because the name isn't as clear\ntype ConstrainedFlagQuery<T> = FlagQuery<\n T extends boolean\n ? boolean\n : T extends number\n ? number\n : T extends string\n ? string\n : T extends JsonValue\n ? T\n : JsonValue\n>;\n\n/**\n * Evaluates a feature flag generically, returning an react-flavored queryable object.\n * The resolver method to use is based on the type of the defaultValue.\n * For type-specific hooks, use {@link useBooleanFlagValue}, {@link useBooleanFlagDetails} and equivalents.\n * By default, components will re-render when the flag value changes.\n * @param {ConstrainedFlagKey<T>} flagKey the flag identifier\n * @template {FlagValue} T A optional generic argument constraining the default.\n * @param {T} defaultValue the default value; used to determine what resolved type should be used.\n * @param {ReactFlagEvaluationOptions} options for this evaluation\n * @returns { FlagQuery } a queryable object containing useful information about the flag.\n */\nexport function useFlag<T extends FlagValue = FlagValue>(\n flagKey: ConstrainedFlagKey<T>,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): FlagQuery<\n T extends boolean\n ? boolean\n : T extends number\n ? number\n : T extends string\n ? string\n : T extends JsonValue\n ? T\n : JsonValue\n> {\n // use the default value to determine the resolver to call\n const query =\n typeof defaultValue === 'boolean'\n ? new HookFlagQuery<boolean>(useBooleanFlagDetails(flagKey, defaultValue, options))\n : typeof defaultValue === 'number'\n ? new HookFlagQuery<number>(useNumberFlagDetails(flagKey, defaultValue, options))\n : typeof defaultValue === 'string'\n ? new HookFlagQuery<string>(useStringFlagDetails(flagKey, defaultValue, options))\n : new HookFlagQuery<JsonValue>(useObjectFlagDetails(flagKey, defaultValue, options));\n // TS sees this as HookFlagQuery<JsonValue>, because the compiler isn't aware of the `typeof` checks above.\n return query as unknown as ConstrainedFlagQuery<T>;\n}\n\n// alias to the return value of useFlag, used to keep useSuspenseFlag consistent\ntype UseFlagReturn<T extends FlagValue> = ReturnType<typeof useFlag<T>>;\n\n/**\n * Equivalent to {@link useFlag} with `options: { suspend: true }`\n * @experimental Suspense is an experimental feature subject to change in future versions.\n * @param {ConstrainedFlagKey<T>} flagKey the flag identifier\n * @template {FlagValue} T A optional generic argument constraining the default.\n * @param {T} defaultValue the default value; used to determine what resolved type should be used.\n * @param {ReactFlagEvaluationNoSuspenseOptions} options for this evaluation\n * @returns { UseFlagReturn<T> } a queryable object containing useful information about the flag.\n */\nexport function useSuspenseFlag<T extends FlagValue = FlagValue>(\n flagKey: ConstrainedFlagKey<T>,\n defaultValue: T,\n options?: ReactFlagEvaluationNoSuspenseOptions,\n): UseFlagReturn<T> {\n return useFlag(flagKey, defaultValue, { ...options, suspendUntilReady: true, suspendWhileReconciling: true });\n}\n\n/**\n * Evaluates a feature flag, returning a boolean.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {BooleanFlagKey} flagKey the flag identifier\n * @param {boolean} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { boolean} a EvaluationDetails object for this evaluation\n */\nexport function useBooleanFlagValue(\n flagKey: BooleanFlagKey,\n defaultValue: boolean,\n options?: ReactFlagEvaluationOptions,\n): boolean {\n return useBooleanFlagDetails(flagKey, defaultValue, options).value;\n}\n\n/**\n * Evaluates a feature flag, returning evaluation details.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {BooleanFlagKey} flagKey the flag identifier\n * @param {boolean} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { EvaluationDetails<boolean>} a EvaluationDetails object for this evaluation\n */\nexport function useBooleanFlagDetails(\n flagKey: BooleanFlagKey,\n defaultValue: boolean,\n options?: ReactFlagEvaluationOptions,\n): EvaluationDetails<boolean> {\n return attachHandlersAndResolve(\n flagKey,\n defaultValue,\n (client) => {\n return client.getBooleanDetails;\n },\n options,\n );\n}\n\n/**\n * Evaluates a feature flag, returning a string.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {StringFlagKey} flagKey the flag identifier\n * @template {string} [T=string] A optional generic argument constraining the string\n * @param {T} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { boolean} a EvaluationDetails object for this evaluation\n */\nexport function useStringFlagValue<T extends string = string>(\n flagKey: StringFlagKey,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): string {\n return useStringFlagDetails(flagKey, defaultValue, options).value;\n}\n\n/**\n * Evaluates a feature flag, returning evaluation details.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {StringFlagKey} flagKey the flag identifier\n * @template {string} [T=string] A optional generic argument constraining the string\n * @param {T} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { EvaluationDetails<string>} a EvaluationDetails object for this evaluation\n */\nexport function useStringFlagDetails<T extends string = string>(\n flagKey: StringFlagKey,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): EvaluationDetails<string> {\n return attachHandlersAndResolve(\n flagKey,\n defaultValue,\n (client) => {\n return client.getStringDetails<T>;\n },\n options,\n );\n}\n\n/**\n * Evaluates a feature flag, returning a number.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {NumberFlagKey} flagKey the flag identifier\n * @template {number} [T=number] A optional generic argument constraining the number\n * @param {T} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { boolean} a EvaluationDetails object for this evaluation\n */\nexport function useNumberFlagValue<T extends number = number>(\n flagKey: NumberFlagKey,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): number {\n return useNumberFlagDetails(flagKey, defaultValue, options).value;\n}\n\n/**\n * Evaluates a feature flag, returning evaluation details.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {NumberFlagKey} flagKey the flag identifier\n * @template {number} [T=number] A optional generic argument constraining the number\n * @param {T} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { EvaluationDetails<number>} a EvaluationDetails object for this evaluation\n */\nexport function useNumberFlagDetails<T extends number = number>(\n flagKey: NumberFlagKey,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): EvaluationDetails<number> {\n return attachHandlersAndResolve(\n flagKey,\n defaultValue,\n (client) => {\n return client.getNumberDetails<T>;\n },\n options,\n );\n}\n\n/**\n * Evaluates a feature flag, returning an object.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {ObjectFlagKey} flagKey the flag identifier\n * @template {JsonValue} [T=JsonValue] A optional generic argument describing the structure\n * @param {T} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { boolean} a EvaluationDetails object for this evaluation\n */\nexport function useObjectFlagValue<T extends JsonValue = JsonValue>(\n flagKey: ObjectFlagKey,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): T {\n return useObjectFlagDetails<T>(flagKey, defaultValue, options).value;\n}\n\n/**\n * Evaluates a feature flag, returning evaluation details.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {ObjectFlagKey} flagKey the flag identifier\n * @param {T} defaultValue the default value\n * @template {JsonValue} [T=JsonValue] A optional generic argument describing the structure\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { EvaluationDetails<T>} a EvaluationDetails object for this evaluation\n */\nexport function useObjectFlagDetails<T extends JsonValue = JsonValue>(\n flagKey: ObjectFlagKey,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): EvaluationDetails<T> {\n return attachHandlersAndResolve(\n flagKey,\n defaultValue,\n (client) => {\n return client.getObjectDetails<T>;\n },\n options,\n );\n}\n\n// determines if a flag should be re-evaluated based on a list of changed flags\nfunction shouldEvaluateFlag(flagKey: string, flagsChanged?: string[]): boolean {\n // if flagsChange is missing entirely, we don't know what to re-render\n return !flagsChanged || flagsChanged.includes(flagKey);\n}\n\nfunction attachHandlersAndResolve<T extends FlagValue>(\n flagKey: string,\n defaultValue: T,\n resolver: (\n client: Client,\n ) => (flagKey: string, defaultValue: T, options?: FlagEvaluationOptions) => EvaluationDetails<T>,\n options?: ReactFlagEvaluationOptions,\n): EvaluationDetails<T> {\n // highest priority > evaluation hook options > provider options > default options > lowest priority\n const defaultedOptions = { ...DEFAULT_OPTIONS, ...useProviderOptions(), ...normalizeOptions(options) };\n const client = useOpenFeatureClient();\n const status = useOpenFeatureClientStatus();\n const provider = useOpenFeatureProvider();\n const isFirstRender = useRef(true);\n\n if (defaultedOptions.suspendUntilReady && status === ProviderStatus.NOT_READY) {\n suspendUntilInitialized(provider, client);\n }\n\n if (defaultedOptions.suspendWhileReconciling && status === ProviderStatus.RECONCILING) {\n suspendUntilReconciled(client);\n }\n\n const [evaluationDetails, setEvaluationDetails] = useState<EvaluationDetails<T>>(() =>\n resolver(client).call(client, flagKey, defaultValue, options),\n );\n\n // Re-evaluate when dependencies change (handles prop changes like flagKey), or if during a re-render, we have detected a change in the evaluated value\n useEffect(() => {\n if (isFirstRender.current) {\n isFirstRender.current = false;\n return;\n }\n\n const newDetails = resolver(client).call(client, flagKey, defaultValue, options);\n if (!isEqual(newDetails, evaluationDetails)) {\n setEvaluationDetails(newDetails);\n }\n }, [client, flagKey, defaultValue, options, resolver, evaluationDetails]);\n\n // Maintain a mutable reference to the evaluation details to have a up-to-date reference in the handlers.\n const evaluationDetailsRef = useRef<EvaluationDetails<T>>(evaluationDetails);\n useEffect(() => {\n evaluationDetailsRef.current = evaluationDetails;\n }, [evaluationDetails]);\n\n const updateEvaluationDetailsCallback = useCallback(() => {\n const updatedEvaluationDetails = resolver(client).call(client, flagKey, defaultValue, options);\n\n /**\n * Avoid re-rendering if the evaluation details haven't changed.\n */\n if (!isEqual(updatedEvaluationDetails, evaluationDetailsRef.current)) {\n setEvaluationDetails(updatedEvaluationDetails);\n }\n }, [client, flagKey, defaultValue, options, resolver]);\n\n const configurationChangeCallback = useCallback<EventHandler<ClientProviderEvents.ConfigurationChanged>>(\n (eventDetails) => {\n if (shouldEvaluateFlag(flagKey, eventDetails?.flagsChanged)) {\n updateEvaluationDetailsCallback();\n }\n },\n [flagKey, updateEvaluationDetailsCallback],\n );\n\n useEffect(() => {\n const controller = new AbortController();\n // Always register the Ready handler to catch provider initialization\n // even if current status is already READY (e.g., from a NoOp provider)\n client.addHandler(ProviderEvents.Ready, updateEvaluationDetailsCallback, { signal: controller.signal });\n\n if (defaultedOptions.updateOnContextChanged) {\n // update when the context changes\n client.addHandler(ProviderEvents.ContextChanged, updateEvaluationDetailsCallback, { signal: controller.signal });\n }\n\n if (defaultedOptions.updateOnConfigurationChanged) {\n // update when the provider configuration changes\n client.addHandler(ProviderEvents.ConfigurationChanged, configurationChangeCallback, {\n signal: controller.signal,\n });\n }\n return () => {\n // cleanup the handlers\n controller.abort();\n };\n }, [\n client,\n defaultedOptions.updateOnContextChanged,\n defaultedOptions.updateOnConfigurationChanged,\n updateEvaluationDetailsCallback,\n configurationChangeCallback,\n ]);\n\n return evaluationDetails;\n}\n", "import type { Client } from '@openfeature/web-sdk';\nimport React from 'react';\nimport type { NormalizedOptions, ReactFlagEvaluationOptions } from '../options';\nimport { normalizeOptions } from '.';\n\n/**\n * The underlying React context.\n *\n * **DO NOT EXPORT PUBLICLY**\n * @internal\n */\nexport const Context = React.createContext<{ client: Client; options: ReactFlagEvaluationOptions } | undefined>(\n undefined,\n);\n\n/**\n * Get a normalized copy of the options used for this OpenFeatureProvider, see {@link normalizeOptions}.\n *\n * **DO NOT EXPORT PUBLICLY**\n * @internal\n * @returns {NormalizedOptions} normalized options the defaulted options, not defaulted or normalized.\n */\nexport function useProviderOptions(): NormalizedOptions {\n const { options } = React.useContext(Context) || {};\n return normalizeOptions(options);\n}\n", "/**\n * Deeply compare two values to determine if they are equal.\n * Supports primitives and serializable objects.\n *\n * Note: Does not handle Date, RegExp, Map, Set, or circular references.\n * Suitable for comparing EvaluationDetails and other JSON-serializable data.\n * @param {unknown} value First value to compare\n * @param {unknown} other Second value to compare\n * @returns {boolean} True if the values are equal\n */\nexport function isEqual(value: unknown, other: unknown): boolean {\n if (value === other) {\n return true;\n }\n\n if (typeof value !== typeof other) {\n return false;\n }\n\n if (typeof value === 'object' && value !== null && typeof other === 'object' && other !== null) {\n const valueKeys = Object.keys(value);\n const otherKeys = Object.keys(other);\n\n if (valueKeys.length !== otherKeys.length) {\n return false;\n }\n\n for (const key of valueKeys) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (!isEqual((value as any)[key], (other as any)[key])) {\n return false;\n }\n }\n\n return true;\n }\n\n return false;\n}\n", "import type { ReactFlagEvaluationOptions, NormalizedOptions } from '../options';\n\n/**\n * Default options.\n * DO NOT EXPORT PUBLICLY\n * @internal\n */\nexport const DEFAULT_OPTIONS: ReactFlagEvaluationOptions = {\n updateOnContextChanged: true,\n updateOnConfigurationChanged: true,\n suspendUntilReady: false,\n suspendWhileReconciling: false,\n};\n\n/**\n * Returns normalization options (all `undefined` fields removed, and `suspend` decomposed to `suspendUntilReady` and `suspendWhileReconciling`).\n * DO NOT EXPORT PUBLICLY\n * @internal\n * @param {ReactFlagEvaluationOptions} options options to normalize\n * @returns {NormalizedOptions} normalized options\n */\nexport const normalizeOptions: (options?: ReactFlagEvaluationOptions) => NormalizedOptions = (\n options: ReactFlagEvaluationOptions = {},\n) => {\n const updateOnContextChanged = options.updateOnContextChanged;\n const updateOnConfigurationChanged = options.updateOnConfigurationChanged;\n\n // fall-back the suspense options to the catch-all `suspend` property\n const suspendUntilReady = 'suspendUntilReady' in options ? options.suspendUntilReady : options.suspend;\n const suspendWhileReconciling =\n 'suspendWhileReconciling' in options ? options.suspendWhileReconciling : options.suspend;\n\n return {\n // only return these if properly set (no undefined to allow overriding with spread)\n ...(typeof suspendUntilReady === 'boolean' && { suspendUntilReady }),\n ...(typeof suspendWhileReconciling === 'boolean' && { suspendWhileReconciling }),\n ...(typeof updateOnContextChanged === 'boolean' && { updateOnContextChanged }),\n ...(typeof updateOnConfigurationChanged === 'boolean' && { updateOnConfigurationChanged }),\n };\n};\n", "import type { Client, Provider } from '@openfeature/web-sdk';\nimport { NOOP_PROVIDER, ProviderEvents } from '@openfeature/web-sdk';\nimport { use } from './use';\n\n/**\n * A weak map is used to store the global suspense status for each provider. It's\n * important for this to be global to avoid rerender loops. Using useRef won't\n * work because the value isn't preserved when a promise is thrown in a component,\n * which is how suspense operates.\n */\nconst globalProviderSuspenseStatus = new WeakMap<Provider, Promise<unknown>>();\n\n/**\n * Suspends until the client is ready to evaluate feature flags.\n *\n * **DO NOT EXPORT PUBLICLY**\n * @internal\n * @param {Provider} provider the provider to suspend for\n * @param {Client} client the client to check for readiness\n */\nexport function suspendUntilInitialized(provider: Provider, client: Client) {\n const statusPromiseRef = globalProviderSuspenseStatus.get(provider);\n if (!statusPromiseRef) {\n // Noop provider is never ready, so we resolve immediately\n const statusPromise = provider !== NOOP_PROVIDER ? isProviderReady(client) : Promise.resolve();\n globalProviderSuspenseStatus.set(provider, statusPromise);\n // Use will throw the promise and React will trigger a rerender when it's resolved\n use(statusPromise);\n } else {\n // Reuse the existing promise, use won't rethrow if the promise has settled.\n use(statusPromiseRef);\n }\n}\n\n/**\n * Suspends until the provider has finished reconciling.\n *\n * **DO NOT EXPORT PUBLICLY**\n * @internal\n * @param {Client} client the client to check for readiness\n */\nexport function suspendUntilReconciled(client: Client) {\n use(isProviderReady(client));\n}\n\nasync function isProviderReady(client: Client) {\n const controller = new AbortController();\n try {\n return await new Promise((resolve, reject) => {\n client.addHandler(ProviderEvents.Ready, resolve, { signal: controller.signal });\n client.addHandler(ProviderEvents.Error, reject, { signal: controller.signal });\n });\n } finally {\n controller.abort();\n }\n}\n", "/// <reference types=\"react/experimental\" />\n// This function is adopted from https://github.com/vercel/swr\nimport React from 'react';\n\n/**\n * Extends a Promise-like value to include status tracking.\n * The extra properties are used to manage the lifecycle of the Promise, indicating its current state.\n * More information can be found in the React RFE for the use hook.\n * @see https://github.com/reactjs/rfcs/pull/229\n */\nexport type UsePromise<T> = Promise<T> & {\n status?: 'pending' | 'fulfilled' | 'rejected';\n value?: T;\n reason?: unknown;\n};\n\n/**\n * React.use is a React API that lets you read the value of a resource like a Promise or context.\n * It was officially added in React 19, so needs to be polyfilled to support older React versions.\n * @param {UsePromise} thenable A thenable object that represents a Promise-like value.\n * @returns {unknown} The resolved value of the thenable or throws if it's still pending or rejected.\n */\nexport const use =\n React.use ||\n // This extra generic is to avoid TypeScript mixing up the generic and JSX syntax\n // and emitting an error.\n // We assume that this is only for the `use(thenable)` case, not `use(context)`.\n // https://github.com/facebook/react/blob/aed00dacfb79d17c53218404c52b1c7aa59c4a89/packages/react-server/src/ReactFizzThenable.js#L45\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n (<T, _>(thenable: UsePromise<T>): T => {\n switch (thenable.status) {\n case 'pending':\n throw thenable;\n case 'fulfilled':\n return thenable.value as T;\n case 'rejected':\n throw thenable.reason;\n default:\n thenable.status = 'pending';\n thenable.then(\n (v) => {\n thenable.status = 'fulfilled';\n thenable.value = v;\n },\n (e) => {\n thenable.status = 'rejected';\n thenable.reason = e;\n },\n );\n throw thenable;\n }\n });\n", "import React from 'react';\nimport { Context } from '../internal';\nimport { type Client } from '@openfeature/web-sdk';\nimport { MissingContextError } from '../internal/errors';\n\n/**\n * Get the {@link Client} instance for this OpenFeatureProvider context.\n * Note that the provider to which this is bound is determined by the OpenFeatureProvider's domain.\n * @returns {Client} client for this scope\n */\nexport function useOpenFeatureClient(): Client {\n const { client } = React.useContext(Context) || {};\n\n if (!client) {\n throw new MissingContextError('No OpenFeature client available');\n }\n\n return client;\n}\n", "const context = 'Components using OpenFeature must be wrapped with an <OpenFeatureProvider>.';\nconst tip =\n 'If you are seeing this in a test, see: https://openfeature.dev/docs/reference/technologies/client/web/react#testing';\n\nexport class MissingContextError extends Error {\n constructor(reason: string) {\n super(`${reason}: ${context} ${tip}`);\n this.name = 'MissingContextError';\n }\n}\n", "import { useEffect, useState } from 'react';\nimport { useOpenFeatureClient } from './use-open-feature-client';\nimport type { ProviderStatus } from '@openfeature/web-sdk';\nimport { ProviderEvents } from '@openfeature/web-sdk';\n\n/**\n * Get the {@link ProviderStatus} for the OpenFeatureClient.\n * Reacts to changes in provider status.\n * @returns {ProviderStatus} status of the client for this scope\n */\nexport function useOpenFeatureClientStatus(): ProviderStatus {\n const client = useOpenFeatureClient();\n const [status, setStatus] = useState<ProviderStatus>(client.providerStatus);\n\n useEffect(() => {\n const controller = new AbortController();\n const updateStatus = () => setStatus(client.providerStatus);\n client.addHandler(ProviderEvents.ConfigurationChanged, updateStatus, { signal: controller.signal });\n client.addHandler(ProviderEvents.ContextChanged, updateStatus, { signal: controller.signal });\n client.addHandler(ProviderEvents.Error, updateStatus, { signal: controller.signal });\n client.addHandler(ProviderEvents.Ready, updateStatus, { signal: controller.signal });\n client.addHandler(ProviderEvents.Stale, updateStatus, { signal: controller.signal });\n client.addHandler(ProviderEvents.Reconciling, updateStatus, { signal: controller.signal });\n return () => {\n controller.abort();\n };\n }, [client]);\n\n return status;\n}\n", "import React from 'react';\nimport { Context } from '../internal';\nimport { OpenFeature } from '@openfeature/web-sdk';\nimport type { Provider } from '@openfeature/web-sdk';\nimport { MissingContextError } from '../internal/errors';\n\n/**\n * Get the {@link Provider} bound to the domain specified in the OpenFeatureProvider context.\n * Note that it isn't recommended to interact with the provider directly, but rather through\n * an OpenFeature client.\n * @returns {Provider} provider for this scope\n */\nexport function useOpenFeatureProvider(): Provider {\n const openFeatureContext = React.useContext(Context);\n\n if (!openFeatureContext) {\n throw new MissingContextError('No OpenFeature context available');\n }\n\n return OpenFeature.getProvider(openFeatureContext.client.metadata.domain);\n}\n", "import type { EvaluationDetails, FlagValue } from '@openfeature/web-sdk';\nimport { StandardResolutionReasons } from '@openfeature/web-sdk';\nimport type { FlagQuery } from '../query';\n\n// FlagQuery implementation, do not export\nexport class HookFlagQuery<T extends FlagValue = FlagValue> implements FlagQuery {\n constructor(private _details: EvaluationDetails<T>) {}\n\n get details() {\n return this._details;\n }\n\n get value() {\n return this._details?.value;\n }\n\n get variant() {\n return this._details.variant;\n }\n\n get flagMetadata() {\n return this._details.flagMetadata;\n }\n\n get reason() {\n return this._details.reason;\n }\n\n get isError() {\n return !!this._details?.errorCode || this._details.reason == StandardResolutionReasons.ERROR;\n }\n\n get errorCode() {\n return this._details?.errorCode;\n }\n\n get errorMessage() {\n return this._details?.errorMessage;\n }\n\n get isAuthoritative() {\n return (\n !this.isError &&\n this._details.reason != StandardResolutionReasons.STALE &&\n this._details.reason != StandardResolutionReasons.DISABLED\n );\n }\n\n get type() {\n return typeof this._details.value;\n }\n}\n", "import type { ClientMetadata, MetadataClient } from './client';\n\n/**\n * Wraps a client so framework metadata is visible through `metadata` and `this.metadata`.\n * @template T\n * @param {T} client client to wrap\n * @param {NonNullable<ClientMetadata['framework']>} framework framework metadata to expose\n * @returns {T} framework-aware client proxy\n */\nexport function withFrameworkMetadata<T extends MetadataClient>(\n client: T,\n framework: NonNullable<ClientMetadata['framework']>,\n): T {\n return new Proxy(client, {\n get(target, property, receiver) {\n if (property === 'metadata') {\n return {\n ...(Reflect.get(target, property, receiver) ?? {}),\n framework,\n };\n }\n\n const value = Reflect.get(target, property, receiver);\n\n if (typeof value !== 'function') {\n return value;\n }\n\n return (...args: unknown[]) => {\n const result = value.apply(receiver, args);\n return result === target ? receiver : result;\n };\n },\n });\n}\n", "import { withFrameworkMetadata } from '@openfeature/core';\nimport type { Client } from '@openfeature/web-sdk';\nimport { OpenFeature } from '@openfeature/web-sdk';\nimport * as React from 'react';\nimport type { ReactFlagEvaluationOptions } from '../options';\nimport { Context } from '../internal';\n\ntype ClientOrDomain =\n | {\n /**\n * An identifier which logically binds clients with providers\n * @see OpenFeature.setProvider() and overloads.\n */\n domain?: string;\n client?: never;\n }\n | {\n /**\n * OpenFeature client to use.\n */\n client?: Client;\n domain?: never;\n };\n\ntype ProviderProps = {\n children?: React.ReactNode;\n} & ClientOrDomain &\n ReactFlagEvaluationOptions;\n\n/**\n * Provides a scope for evaluating feature flags by binding a client to all child components.\n * @param {ProviderProps} properties props for the context provider\n * @returns {OpenFeatureProvider} context provider\n */\nexport function OpenFeatureProvider({ client, domain, children, ...options }: ProviderProps) {\n const stableClient = React.useMemo(\n () => withFrameworkMetadata(client || OpenFeature.getClient(domain), 'react'),\n [client, domain],\n );\n\n return <Context.Provider value={{ client: stableClient, options }}>{children}</Context.Provider>;\n}\n", "import { ProviderStatus } from '@openfeature/web-sdk';\nimport { useOpenFeatureClient } from './use-open-feature-client';\nimport { useOpenFeatureClientStatus } from './use-open-feature-client-status';\nimport type { ReactFlagEvaluationOptions } from '../options';\nimport { DEFAULT_OPTIONS, useProviderOptions, normalizeOptions, suspendUntilInitialized } from '../internal';\nimport { useOpenFeatureProvider } from './use-open-feature-provider';\n\ntype Options = Pick<ReactFlagEvaluationOptions, 'suspendUntilReady'>;\n\n/**\n * Utility hook that triggers suspense until the provider is {@link ProviderStatus.READY}, without evaluating any flags.\n * Especially useful for React v16/17 \"Legacy Suspense\", in which siblings to suspending components are\n * initially mounted and then hidden (see: https://github.com/reactwg/react-18/discussions/7).\n *\n * NOTE: This hook returns true only when the provider status is {@link ProviderStatus.READY}.\n * For other statuses (ERROR, STALE, FATAL, RECONCILING), use {@link useOpenFeatureClientStatus}.\n * @param {Options} options options for suspense\n * @returns {boolean} boolean indicating if provider is {@link ProviderStatus.READY}, useful if suspense is disabled and you want to handle loaders on your own\n */\nexport function useWhenProviderReady(options?: Options): boolean {\n // highest priority > evaluation hook options > provider options > default options > lowest priority\n const defaultedOptions = { ...DEFAULT_OPTIONS, ...useProviderOptions(), ...normalizeOptions(options) };\n const client = useOpenFeatureClient();\n const status = useOpenFeatureClientStatus();\n const provider = useOpenFeatureProvider();\n\n if (defaultedOptions.suspendUntilReady && status === ProviderStatus.NOT_READY) {\n suspendUntilInitialized(provider, client);\n }\n\n return status === ProviderStatus.READY;\n}\n", "import type { InMemoryFlagConfiguration, JsonValue, Provider } from '@openfeature/web-sdk';\nimport { TypedInMemoryProvider, NOOP_PROVIDER, OpenFeature } from '@openfeature/web-sdk';\nimport React from 'react';\nimport type { NormalizedOptions } from '../options';\nimport { OpenFeatureProvider } from './provider';\n\ntype FlagValueMap = { [flagKey: string]: JsonValue };\ntype TestProviderProps = Omit<React.ComponentProps<typeof OpenFeatureProvider>, 'client'> &\n (\n | {\n provider?: never;\n /**\n * Optional map of flagKeys to flagValues for this OpenFeatureTestProvider context.\n * If not supplied, all flag evaluations will default.\n */\n flagValueMap?: FlagValueMap;\n /**\n * Optional delay for the underlying test provider's readiness and reconciliation.\n * Defaults to 0.\n */\n delayMs?: number;\n }\n | {\n /**\n * An optional partial provider to pass for full control over the flag resolution for this OpenFeatureTestProvider context.\n * Any un-implemented methods or properties will no-op.\n */\n provider?: Partial<Provider>;\n flagValueMap?: never;\n delayMs?: never;\n }\n );\n\nconst TEST_VARIANT = 'test-variant';\nconst TEST_PROVIDER = 'test-provider';\n\n// internal provider which is basically the in-memory provider with a simpler config and some optional fake delays\nclass TestProvider extends TypedInMemoryProvider {\n // initially make this undefined, we still set it if a delay is specified\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore - For maximum compatibility with previous versions, we ignore a possible TS error here,\n // since \"initialize\" was previously defined in superclass.\n // We can safely remove this ts-ignore in a few versions\n initialize: Provider['initialize'] = undefined;\n\n // \"place-holder\" init function which we only assign if want a delay\n private delayedInitialize = async () => {\n await new Promise<void>((resolve) => setTimeout(resolve, this.delay));\n };\n\n constructor(\n flagValueMap: FlagValueMap,\n private delay = 0,\n ) {\n // convert the simple flagValueMap into an in-memory config\n const flagConfig = Object.entries(flagValueMap).reduce(\n (acc: InMemoryFlagConfiguration, flag): InMemoryFlagConfiguration => {\n return {\n ...acc,\n [flag[0]]: {\n variants: {\n [TEST_VARIANT]: flag[1],\n },\n defaultVariant: TEST_VARIANT,\n disabled: false,\n },\n };\n },\n {},\n );\n super(flagConfig);\n // only define and init if there's a non-zero delay specified\n this.initialize = this.delay ? this.delayedInitialize.bind(this) : undefined;\n }\n\n async onContextChange() {\n return new Promise<void>((resolve) => setTimeout(resolve, this.delay));\n }\n}\n\n/**\n * A React Context provider based on the {@link TypedInMemoryProvider}, specifically built for testing.\n * Use this for testing components that use flag evaluation hooks.\n * @param {TestProviderProps} testProviderOptions options for the OpenFeatureTestProvider\n * @returns {OpenFeatureProvider} OpenFeatureTestProvider\n */\nexport function OpenFeatureTestProvider(testProviderOptions: TestProviderProps) {\n const { flagValueMap, provider } = testProviderOptions;\n const effectiveProvider = (\n flagValueMap ? new TestProvider(flagValueMap, testProviderOptions.delayMs) : mixInNoop(provider) || NOOP_PROVIDER\n ) as Provider;\n testProviderOptions.domain\n ? OpenFeature.setProvider(testProviderOptions.domain, effectiveProvider)\n : OpenFeature.setProvider(effectiveProvider);\n\n return (\n <OpenFeatureProvider {...(testProviderOptions as NormalizedOptions)} domain={testProviderOptions.domain}>\n {testProviderOptions.children}\n </OpenFeatureProvider>\n );\n}\n\n// mix in the no-op provider when the partial is passed\nfunction mixInNoop(provider: Partial<Provider> = {}) {\n // fill in any missing methods with no-ops\n for (const prop of Object.getOwnPropertyNames(Object.getPrototypeOf(NOOP_PROVIDER)).filter(\n (prop) => prop !== 'constructor',\n )) {\n const patchedProvider = provider as { [key: string]: keyof Provider };\n if (!Object.getPrototypeOf(patchedProvider)[prop] && !patchedProvider[prop]) {\n patchedProvider[prop] = Object.getPrototypeOf(NOOP_PROVIDER)[prop];\n }\n }\n // fill in the metadata if missing\n if (!provider.metadata || !provider.metadata.name) {\n (provider.metadata as unknown) = { name: TEST_PROVIDER };\n }\n return provider;\n}\n", "import { useCallback, useContext, useEffect, useState } from 'react';\nimport type { EvaluationContext } from '@openfeature/web-sdk';\nimport { OpenFeature } from '@openfeature/web-sdk';\nimport { Context } from '../internal';\n\nexport type ContextMutationOptions = {\n /**\n * Mutate the default context instead of the domain scoped context applied at the `<OpenFeatureProvider/>`.\n * By default, will use the domain set on `<OpenFeatureProvider/>` (or the domain associated with the client set on `<OpenFeatureProvider/>`).\n * See the {@link https://openfeature.dev/docs/reference/technologies/client/web/#manage-evaluation-context-for-domains|documentation} for more information.\n * @default false\n */\n defaultContext?: boolean;\n};\n\nexport type ContextMutation = {\n /**\n * Context-aware function to set the desired context (see: {@link ContextMutationOptions} for details).\n * There's generally no need to await the result of this function; flag evaluation hooks will re-render when the context is updated.\n * This promise never rejects.\n * @param updatedContext New context object or method to generate it from the current context\n * @returns Promise for awaiting the context update\n */\n setContext: (\n updatedContext: EvaluationContext | ((currentContext: EvaluationContext) => EvaluationContext),\n ) => Promise<void>;\n};\n\n/**\n * Get context-aware tracking function(s) for mutating the evaluation context associated with this domain, or the default context if `defaultContext: true`.\n * See the {@link https://openfeature.dev/docs/reference/technologies/client/web/#targeting-and-context|documentation} for more information.\n * @param {ContextMutationOptions} options options for the generated function\n * @returns {ContextMutation} context-aware function(s) to mutate evaluation context\n */\nexport function useContextMutator(options: ContextMutationOptions = { defaultContext: false }): ContextMutation {\n const { client } = useContext(Context) || {};\n const domain = client?.metadata.domain;\n\n // TODO: Replace this warning with a thrown error in a future major release,\n // to match the behavior of `useOpenFeatureProvider` + `useOpenFeatureClient`,\n // when `defaultContext` isn't explicitly set to true.\n const [warned, setWarned] = useState(false);\n useEffect(() => {\n if (options.defaultContext || domain) {\n if (warned) {\n setWarned(false);\n }\n return;\n }\n\n if (!warned) {\n console.warn(\n '[useContextMutator] No domain available from OpenFeature context; are you using <OpenFeatureProvider/>? setContext will mutate the default context, as if `defaultContext: true` were set. This may result in a thrown error in the future.',\n );\n setWarned(true);\n }\n }, [warned]);\n\n const setContext = useCallback(\n async (\n updatedContext: EvaluationContext | ((currentContext: EvaluationContext) => EvaluationContext),\n ): Promise<void> => {\n const previousContext = OpenFeature.getContext(options?.defaultContext ? undefined : domain);\n const resolvedContext = typeof updatedContext === 'function' ? updatedContext(previousContext) : updatedContext;\n\n if (previousContext !== resolvedContext) {\n if (!domain || options?.defaultContext) {\n await OpenFeature.setContext(resolvedContext);\n } else {\n await OpenFeature.setContext(domain, resolvedContext);\n }\n }\n },\n [domain, options?.defaultContext],\n );\n\n return {\n setContext,\n };\n}\n", "import type { Tracking, TrackingEventDetails } from '@openfeature/web-sdk';\nimport { useCallback } from 'react';\nimport { useOpenFeatureClient } from '../provider';\n\nexport type Track = {\n /**\n * Context-aware tracking function for the parent `<OpenFeatureProvider/>`.\n * Track a user action or application state, usually representing a business objective or outcome.\n * @param trackingEventName an identifier for the event\n * @param trackingEventDetails the details of the tracking event\n */\n track: Tracking['track'];\n};\n\n/**\n * Get a context-aware tracking function.\n * @returns {Track} context-aware tracking\n */\nexport function useTrack(): Track {\n const client = useOpenFeatureClient();\n\n const track = useCallback((trackingEventName: string, trackingEventDetails?: TrackingEventDetails) => {\n client.track(trackingEventName, trackingEventDetails);\n }, []);\n\n return {\n track,\n };\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["import_react", "import_web_sdk", "import_react", "React", "import_react", "React", "import_react", "React", "import_react", "import_web_sdk", "import_react", "import_web_sdk", "React", "import_web_sdk", "fallbackNode", "React", "import_web_sdk", "React", "import_web_sdk", "import_web_sdk", "import_react", "React", "prop", "import_react", "import_web_sdk", "import_react"]
7
7
  }
package/dist/esm/index.js CHANGED
@@ -434,12 +434,37 @@ function FeatureFlag({
434
434
  return /* @__PURE__ */ React5.createElement(React5.Fragment, null, fallbackNode);
435
435
  }
436
436
 
437
+ // ../shared/src/client/framework-metadata.ts
438
+ function withFrameworkMetadata(client, framework) {
439
+ return new Proxy(client, {
440
+ get(target, property, receiver) {
441
+ var _a;
442
+ if (property === "metadata") {
443
+ return __spreadProps(__spreadValues({}, (_a = Reflect.get(target, property, receiver)) != null ? _a : {}), {
444
+ framework
445
+ });
446
+ }
447
+ const value = Reflect.get(target, property, receiver);
448
+ if (typeof value !== "function") {
449
+ return value;
450
+ }
451
+ return (...args) => {
452
+ const result = value.apply(receiver, args);
453
+ return result === target ? receiver : result;
454
+ };
455
+ }
456
+ });
457
+ }
458
+
437
459
  // src/provider/provider.tsx
438
460
  import { OpenFeature as OpenFeature2 } from "@openfeature/web-sdk";
439
461
  import * as React6 from "react";
440
462
  function OpenFeatureProvider(_a) {
441
463
  var _b = _a, { client, domain, children } = _b, options = __objRest(_b, ["client", "domain", "children"]);
442
- const stableClient = React6.useMemo(() => client || OpenFeature2.getClient(domain), [client, domain]);
464
+ const stableClient = React6.useMemo(
465
+ () => withFrameworkMetadata(client || OpenFeature2.getClient(domain), "react"),
466
+ [client, domain]
467
+ );
443
468
  return /* @__PURE__ */ React6.createElement(Context.Provider, { value: { client: stableClient, options } }, children);
444
469
  }
445
470
 
@@ -457,23 +482,26 @@ function useWhenProviderReady(options) {
457
482
  }
458
483
 
459
484
  // src/provider/test-provider.tsx
460
- import { InMemoryProvider, NOOP_PROVIDER as NOOP_PROVIDER2, OpenFeature as OpenFeature3 } from "@openfeature/web-sdk";
485
+ import { TypedInMemoryProvider, NOOP_PROVIDER as NOOP_PROVIDER2, OpenFeature as OpenFeature3 } from "@openfeature/web-sdk";
461
486
  import React7 from "react";
462
487
  var TEST_VARIANT = "test-variant";
463
488
  var TEST_PROVIDER = "test-provider";
464
- var TestProvider = class extends InMemoryProvider {
489
+ var TestProvider = class extends TypedInMemoryProvider {
465
490
  constructor(flagValueMap, delay = 0) {
466
- const flagConfig = Object.entries(flagValueMap).reduce((acc, flag) => {
467
- return __spreadProps(__spreadValues({}, acc), {
468
- [flag[0]]: {
469
- variants: {
470
- [TEST_VARIANT]: flag[1]
471
- },
472
- defaultVariant: TEST_VARIANT,
473
- disabled: false
474
- }
475
- });
476
- }, {});
491
+ const flagConfig = Object.entries(flagValueMap).reduce(
492
+ (acc, flag) => {
493
+ return __spreadProps(__spreadValues({}, acc), {
494
+ [flag[0]]: {
495
+ variants: {
496
+ [TEST_VARIANT]: flag[1]
497
+ },
498
+ defaultVariant: TEST_VARIANT,
499
+ disabled: false
500
+ }
501
+ });
502
+ },
503
+ {}
504
+ );
477
505
  super(flagConfig);
478
506
  this.delay = delay;
479
507
  // initially make this undefined, we still set it if a delay is specified
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/declarative/FeatureFlag.tsx", "../../src/evaluation/use-feature-flag.ts", "../../src/internal/context.ts", "../../src/internal/is-equal.ts", "../../src/internal/options.ts", "../../src/internal/suspense.ts", "../../src/internal/use.ts", "../../src/provider/use-open-feature-client.ts", "../../src/internal/errors.ts", "../../src/provider/use-open-feature-client-status.ts", "../../src/provider/use-open-feature-provider.ts", "../../src/internal/hook-flag-query.ts", "../../src/provider/provider.tsx", "../../src/provider/use-when-provider-ready.ts", "../../src/provider/test-provider.tsx", "../../src/context/use-context-mutator.ts", "../../src/tracking/use-track.ts", "../../src/index.ts"],
4
- "sourcesContent": ["import React from 'react';\nimport { useFlag } from '../evaluation';\nimport type { FlagQuery } from '../query';\nimport type { FlagValue, EvaluationDetails } from '@openfeature/core';\nimport { isEqual } from '../internal';\nimport type { ReactFlagEvaluationOptions } from '../options';\n\n/**\n * Default predicate function that checks if the expected value equals the actual flag value.\n * @param {T} expected The expected value to match against\n * @param {EvaluationDetails<T>} actual The evaluation details containing the actual flag value\n * @returns {boolean} true if the values match, false otherwise\n */\nfunction equals<T extends FlagValue>(expected: T, actual: EvaluationDetails<T>): boolean {\n return isEqual(expected, actual.value);\n}\n\n/**\n * Props for the FeatureFlag component that conditionally renders content based on feature flag state.\n * @interface FeatureFlagProps\n */\ninterface FeatureFlagProps<T extends FlagValue = FlagValue> {\n /**\n * The key of the feature flag to evaluate.\n */\n flagKey: string;\n\n /**\n * Optional predicate function for custom matching logic.\n * If provided, this function will be used instead of the default equality check.\n * @param matchValue The value to match (matchValue prop)\n * @param details The evaluation details\n * @returns true if the condition is met, false otherwise\n */\n predicate?: (matchValue: T | undefined, details: EvaluationDetails<T>) => boolean;\n\n /**\n * Content to render when the feature flag condition is met.\n * Can be a React node or a function that receives flag query details and returns a React node.\n */\n children: React.ReactNode | ((details: FlagQuery<T>) => React.ReactNode);\n\n /**\n * Optional content to render when the feature flag condition is not met.\n * Can be a React node or a function that receives evaluation details and returns a React node.\n */\n fallback?: React.ReactNode | ((details: EvaluationDetails<T>) => React.ReactNode);\n\n /**\n * Flag evaluation options that will be passed to useFlag hook.\n */\n evaluationOptions?: ReactFlagEvaluationOptions;\n}\n\n/**\n * Configuration for matching flag values.\n * For boolean flags, `match` is optional (defaults to checking truthiness).\n * For non-boolean flags (string, number, object), `match` is required to determine when to render.\n */\ntype FeatureFlagMatchConfig<T extends FlagValue> = {\n /**\n * Default value to use when the feature flag is not found.\n */\n defaultValue: T;\n} & (T extends boolean\n ? {\n /**\n * Optional value to match against the feature flag value.\n */\n matchValue?: T | undefined;\n }\n : {\n /**\n * Value to match against the feature flag value.\n * Required for non-boolean flags to determine when children should render.\n * By default, strict equality is used for comparison.\n */\n matchValue: T;\n });\n\ntype FeatureFlagComponentProps<T extends FlagValue> = FeatureFlagProps<T> & FeatureFlagMatchConfig<T>;\n\n/**\n * @experimental This API is experimental, and is subject to change.\n * FeatureFlag component that conditionally renders its children based on the evaluation of a feature flag.\n * @param {FeatureFlagComponentProps} props The properties for the FeatureFlag component.\n * @returns {React.ReactElement | null} The rendered component or null if the feature is not enabled.\n */\nexport function FeatureFlag<T extends FlagValue = FlagValue>({\n flagKey,\n matchValue,\n predicate,\n defaultValue,\n children,\n evaluationOptions = {},\n fallback = null,\n}: FeatureFlagComponentProps<T>): React.ReactElement | null {\n const details = useFlag(flagKey, defaultValue, {\n updateOnContextChanged: true,\n ...evaluationOptions,\n });\n\n // If the flag evaluation failed, we render the fallback\n if (details.reason === 'ERROR') {\n const fallbackNode: React.ReactNode =\n typeof fallback === 'function' ? fallback(details.details as EvaluationDetails<T>) : fallback;\n return <>{fallbackNode}</>;\n }\n\n // Use custom predicate if provided, otherwise use default matching logic\n let shouldRender = false;\n if (predicate) {\n shouldRender = predicate(matchValue as T, details.details as EvaluationDetails<T>);\n } else if (matchValue !== undefined) {\n // Default behavior: check if match value equals flag value\n shouldRender = equals(matchValue, details.details as EvaluationDetails<T>);\n } else if (details.type === 'boolean') {\n // If no match value is provided, render if flag is truthy\n shouldRender = Boolean(details.value);\n } else {\n shouldRender = false;\n }\n\n if (shouldRender) {\n const childNode: React.ReactNode = typeof children === 'function' ? children(details as FlagQuery<T>) : children;\n return <>{childNode}</>;\n }\n\n const fallbackNode: React.ReactNode =\n typeof fallback === 'function' ? fallback(details.details as EvaluationDetails<T>) : fallback;\n return <>{fallbackNode}</>;\n}\n", "import type {\n Client,\n ClientProviderEvents,\n EvaluationDetails,\n EventHandler,\n FlagEvaluationOptions,\n FlagValue,\n JsonValue,\n} from '@openfeature/web-sdk';\nimport { ProviderEvents, ProviderStatus } from '@openfeature/web-sdk';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport {\n DEFAULT_OPTIONS,\n isEqual,\n normalizeOptions,\n suspendUntilInitialized,\n suspendUntilReconciled,\n useProviderOptions,\n} from '../internal';\nimport type { ReactFlagEvaluationNoSuspenseOptions, ReactFlagEvaluationOptions } from '../options';\nimport { useOpenFeatureClient } from '../provider/use-open-feature-client';\nimport { useOpenFeatureClientStatus } from '../provider/use-open-feature-client-status';\nimport { useOpenFeatureProvider } from '../provider/use-open-feature-provider';\nimport type { FlagQuery } from '../query';\nimport { HookFlagQuery } from '../internal/hook-flag-query';\n\n// This type is a bit wild-looking, but I think we need it.\n// We have to use the conditional, because otherwise useFlag('key', false) would return false, not boolean (too constrained).\n// We have a duplicate for the hook return below, this one is just used for casting because the name isn't as clear\ntype ConstrainedFlagQuery<T> = FlagQuery<\n T extends boolean\n ? boolean\n : T extends number\n ? number\n : T extends string\n ? string\n : T extends JsonValue\n ? T\n : JsonValue\n>;\n\n/**\n * Evaluates a feature flag generically, returning an react-flavored queryable object.\n * The resolver method to use is based on the type of the defaultValue.\n * For type-specific hooks, use {@link useBooleanFlagValue}, {@link useBooleanFlagDetails} and equivalents.\n * By default, components will re-render when the flag value changes.\n * @param {string} flagKey the flag identifier\n * @template {FlagValue} T A optional generic argument constraining the default.\n * @param {T} defaultValue the default value; used to determine what resolved type should be used.\n * @param {ReactFlagEvaluationOptions} options for this evaluation\n * @returns { FlagQuery } a queryable object containing useful information about the flag.\n */\nexport function useFlag<T extends FlagValue = FlagValue>(\n flagKey: string,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): FlagQuery<\n T extends boolean\n ? boolean\n : T extends number\n ? number\n : T extends string\n ? string\n : T extends JsonValue\n ? T\n : JsonValue\n> {\n // use the default value to determine the resolver to call\n const query =\n typeof defaultValue === 'boolean'\n ? new HookFlagQuery<boolean>(useBooleanFlagDetails(flagKey, defaultValue, options))\n : typeof defaultValue === 'number'\n ? new HookFlagQuery<number>(useNumberFlagDetails(flagKey, defaultValue, options))\n : typeof defaultValue === 'string'\n ? new HookFlagQuery<string>(useStringFlagDetails(flagKey, defaultValue, options))\n : new HookFlagQuery<JsonValue>(useObjectFlagDetails(flagKey, defaultValue, options));\n // TS sees this as HookFlagQuery<JsonValue>, because the compiler isn't aware of the `typeof` checks above.\n return query as unknown as ConstrainedFlagQuery<T>;\n}\n\n// alias to the return value of useFlag, used to keep useSuspenseFlag consistent\ntype UseFlagReturn<T extends FlagValue> = ReturnType<typeof useFlag<T>>;\n\n/**\n * Equivalent to {@link useFlag} with `options: { suspend: true }`\n * @experimental Suspense is an experimental feature subject to change in future versions.\n * @param {string} flagKey the flag identifier\n * @template {FlagValue} T A optional generic argument constraining the default.\n * @param {T} defaultValue the default value; used to determine what resolved type should be used.\n * @param {ReactFlagEvaluationNoSuspenseOptions} options for this evaluation\n * @returns { UseFlagReturn<T> } a queryable object containing useful information about the flag.\n */\nexport function useSuspenseFlag<T extends FlagValue = FlagValue>(\n flagKey: string,\n defaultValue: T,\n options?: ReactFlagEvaluationNoSuspenseOptions,\n): UseFlagReturn<T> {\n return useFlag(flagKey, defaultValue, { ...options, suspendUntilReady: true, suspendWhileReconciling: true });\n}\n\n/**\n * Evaluates a feature flag, returning a boolean.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {string} flagKey the flag identifier\n * @param {boolean} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { boolean} a EvaluationDetails object for this evaluation\n */\nexport function useBooleanFlagValue(\n flagKey: string,\n defaultValue: boolean,\n options?: ReactFlagEvaluationOptions,\n): boolean {\n return useBooleanFlagDetails(flagKey, defaultValue, options).value;\n}\n\n/**\n * Evaluates a feature flag, returning evaluation details.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {string} flagKey the flag identifier\n * @param {boolean} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { EvaluationDetails<boolean>} a EvaluationDetails object for this evaluation\n */\nexport function useBooleanFlagDetails(\n flagKey: string,\n defaultValue: boolean,\n options?: ReactFlagEvaluationOptions,\n): EvaluationDetails<boolean> {\n return attachHandlersAndResolve(\n flagKey,\n defaultValue,\n (client) => {\n return client.getBooleanDetails;\n },\n options,\n );\n}\n\n/**\n * Evaluates a feature flag, returning a string.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {string} flagKey the flag identifier\n * @template {string} [T=string] A optional generic argument constraining the string\n * @param {T} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { boolean} a EvaluationDetails object for this evaluation\n */\nexport function useStringFlagValue<T extends string = string>(\n flagKey: string,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): string {\n return useStringFlagDetails(flagKey, defaultValue, options).value;\n}\n\n/**\n * Evaluates a feature flag, returning evaluation details.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {string} flagKey the flag identifier\n * @template {string} [T=string] A optional generic argument constraining the string\n * @param {T} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { EvaluationDetails<string>} a EvaluationDetails object for this evaluation\n */\nexport function useStringFlagDetails<T extends string = string>(\n flagKey: string,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): EvaluationDetails<string> {\n return attachHandlersAndResolve(\n flagKey,\n defaultValue,\n (client) => {\n return client.getStringDetails<T>;\n },\n options,\n );\n}\n\n/**\n * Evaluates a feature flag, returning a number.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {string} flagKey the flag identifier\n * @template {number} [T=number] A optional generic argument constraining the number\n * @param {T} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { boolean} a EvaluationDetails object for this evaluation\n */\nexport function useNumberFlagValue<T extends number = number>(\n flagKey: string,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): number {\n return useNumberFlagDetails(flagKey, defaultValue, options).value;\n}\n\n/**\n * Evaluates a feature flag, returning evaluation details.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {string} flagKey the flag identifier\n * @template {number} [T=number] A optional generic argument constraining the number\n * @param {T} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { EvaluationDetails<number>} a EvaluationDetails object for this evaluation\n */\nexport function useNumberFlagDetails<T extends number = number>(\n flagKey: string,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): EvaluationDetails<number> {\n return attachHandlersAndResolve(\n flagKey,\n defaultValue,\n (client) => {\n return client.getNumberDetails<T>;\n },\n options,\n );\n}\n\n/**\n * Evaluates a feature flag, returning an object.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {string} flagKey the flag identifier\n * @template {JsonValue} [T=JsonValue] A optional generic argument describing the structure\n * @param {T} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { boolean} a EvaluationDetails object for this evaluation\n */\nexport function useObjectFlagValue<T extends JsonValue = JsonValue>(\n flagKey: string,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): T {\n return useObjectFlagDetails<T>(flagKey, defaultValue, options).value;\n}\n\n/**\n * Evaluates a feature flag, returning evaluation details.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {string} flagKey the flag identifier\n * @param {T} defaultValue the default value\n * @template {JsonValue} [T=JsonValue] A optional generic argument describing the structure\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { EvaluationDetails<T>} a EvaluationDetails object for this evaluation\n */\nexport function useObjectFlagDetails<T extends JsonValue = JsonValue>(\n flagKey: string,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): EvaluationDetails<T> {\n return attachHandlersAndResolve(\n flagKey,\n defaultValue,\n (client) => {\n return client.getObjectDetails<T>;\n },\n options,\n );\n}\n\n// determines if a flag should be re-evaluated based on a list of changed flags\nfunction shouldEvaluateFlag(flagKey: string, flagsChanged?: string[]): boolean {\n // if flagsChange is missing entirely, we don't know what to re-render\n return !flagsChanged || flagsChanged.includes(flagKey);\n}\n\nfunction attachHandlersAndResolve<T extends FlagValue>(\n flagKey: string,\n defaultValue: T,\n resolver: (\n client: Client,\n ) => (flagKey: string, defaultValue: T, options?: FlagEvaluationOptions) => EvaluationDetails<T>,\n options?: ReactFlagEvaluationOptions,\n): EvaluationDetails<T> {\n // highest priority > evaluation hook options > provider options > default options > lowest priority\n const defaultedOptions = { ...DEFAULT_OPTIONS, ...useProviderOptions(), ...normalizeOptions(options) };\n const client = useOpenFeatureClient();\n const status = useOpenFeatureClientStatus();\n const provider = useOpenFeatureProvider();\n const isFirstRender = useRef(true);\n\n if (defaultedOptions.suspendUntilReady && status === ProviderStatus.NOT_READY) {\n suspendUntilInitialized(provider, client);\n }\n\n if (defaultedOptions.suspendWhileReconciling && status === ProviderStatus.RECONCILING) {\n suspendUntilReconciled(client);\n }\n\n const [evaluationDetails, setEvaluationDetails] = useState<EvaluationDetails<T>>(() =>\n resolver(client).call(client, flagKey, defaultValue, options),\n );\n\n // Re-evaluate when dependencies change (handles prop changes like flagKey), or if during a re-render, we have detected a change in the evaluated value\n useEffect(() => {\n if (isFirstRender.current) {\n isFirstRender.current = false;\n return;\n }\n\n const newDetails = resolver(client).call(client, flagKey, defaultValue, options);\n if (!isEqual(newDetails, evaluationDetails)) {\n setEvaluationDetails(newDetails);\n }\n }, [client, flagKey, defaultValue, options, resolver, evaluationDetails]);\n\n // Maintain a mutable reference to the evaluation details to have a up-to-date reference in the handlers.\n const evaluationDetailsRef = useRef<EvaluationDetails<T>>(evaluationDetails);\n useEffect(() => {\n evaluationDetailsRef.current = evaluationDetails;\n }, [evaluationDetails]);\n\n const updateEvaluationDetailsCallback = useCallback(() => {\n const updatedEvaluationDetails = resolver(client).call(client, flagKey, defaultValue, options);\n\n /**\n * Avoid re-rendering if the evaluation details haven't changed.\n */\n if (!isEqual(updatedEvaluationDetails, evaluationDetailsRef.current)) {\n setEvaluationDetails(updatedEvaluationDetails);\n }\n }, [client, flagKey, defaultValue, options, resolver]);\n\n const configurationChangeCallback = useCallback<EventHandler<ClientProviderEvents.ConfigurationChanged>>(\n (eventDetails) => {\n if (shouldEvaluateFlag(flagKey, eventDetails?.flagsChanged)) {\n updateEvaluationDetailsCallback();\n }\n },\n [flagKey, updateEvaluationDetailsCallback],\n );\n\n useEffect(() => {\n const controller = new AbortController();\n // Always register the Ready handler to catch provider initialization\n // even if current status is already READY (e.g., from a NoOp provider)\n client.addHandler(ProviderEvents.Ready, updateEvaluationDetailsCallback, { signal: controller.signal });\n\n if (defaultedOptions.updateOnContextChanged) {\n // update when the context changes\n client.addHandler(ProviderEvents.ContextChanged, updateEvaluationDetailsCallback, { signal: controller.signal });\n }\n\n if (defaultedOptions.updateOnConfigurationChanged) {\n // update when the provider configuration changes\n client.addHandler(ProviderEvents.ConfigurationChanged, configurationChangeCallback, {\n signal: controller.signal,\n });\n }\n return () => {\n // cleanup the handlers\n controller.abort();\n };\n }, [\n client,\n defaultedOptions.updateOnContextChanged,\n defaultedOptions.updateOnConfigurationChanged,\n updateEvaluationDetailsCallback,\n configurationChangeCallback,\n ]);\n\n return evaluationDetails;\n}\n", "import type { Client } from '@openfeature/web-sdk';\nimport React from 'react';\nimport type { NormalizedOptions, ReactFlagEvaluationOptions } from '../options';\nimport { normalizeOptions } from '.';\n\n/**\n * The underlying React context.\n *\n * **DO NOT EXPORT PUBLICLY**\n * @internal\n */\nexport const Context = React.createContext<{ client: Client; options: ReactFlagEvaluationOptions } | undefined>(\n undefined,\n);\n\n/**\n * Get a normalized copy of the options used for this OpenFeatureProvider, see {@link normalizeOptions}.\n *\n * **DO NOT EXPORT PUBLICLY**\n * @internal\n * @returns {NormalizedOptions} normalized options the defaulted options, not defaulted or normalized.\n */\nexport function useProviderOptions(): NormalizedOptions {\n const { options } = React.useContext(Context) || {};\n return normalizeOptions(options);\n}\n", "/**\n * Deeply compare two values to determine if they are equal.\n * Supports primitives and serializable objects.\n *\n * Note: Does not handle Date, RegExp, Map, Set, or circular references.\n * Suitable for comparing EvaluationDetails and other JSON-serializable data.\n * @param {unknown} value First value to compare\n * @param {unknown} other Second value to compare\n * @returns {boolean} True if the values are equal\n */\nexport function isEqual(value: unknown, other: unknown): boolean {\n if (value === other) {\n return true;\n }\n\n if (typeof value !== typeof other) {\n return false;\n }\n\n if (typeof value === 'object' && value !== null && typeof other === 'object' && other !== null) {\n const valueKeys = Object.keys(value);\n const otherKeys = Object.keys(other);\n\n if (valueKeys.length !== otherKeys.length) {\n return false;\n }\n\n for (const key of valueKeys) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (!isEqual((value as any)[key], (other as any)[key])) {\n return false;\n }\n }\n\n return true;\n }\n\n return false;\n}\n", "import type { ReactFlagEvaluationOptions, NormalizedOptions } from '../options';\n\n/**\n * Default options.\n * DO NOT EXPORT PUBLICLY\n * @internal\n */\nexport const DEFAULT_OPTIONS: ReactFlagEvaluationOptions = {\n updateOnContextChanged: true,\n updateOnConfigurationChanged: true,\n suspendUntilReady: false,\n suspendWhileReconciling: false,\n};\n\n/**\n * Returns normalization options (all `undefined` fields removed, and `suspend` decomposed to `suspendUntilReady` and `suspendWhileReconciling`).\n * DO NOT EXPORT PUBLICLY\n * @internal\n * @param {ReactFlagEvaluationOptions} options options to normalize\n * @returns {NormalizedOptions} normalized options\n */\nexport const normalizeOptions: (options?: ReactFlagEvaluationOptions) => NormalizedOptions = (\n options: ReactFlagEvaluationOptions = {},\n) => {\n const updateOnContextChanged = options.updateOnContextChanged;\n const updateOnConfigurationChanged = options.updateOnConfigurationChanged;\n\n // fall-back the suspense options to the catch-all `suspend` property\n const suspendUntilReady = 'suspendUntilReady' in options ? options.suspendUntilReady : options.suspend;\n const suspendWhileReconciling =\n 'suspendWhileReconciling' in options ? options.suspendWhileReconciling : options.suspend;\n\n return {\n // only return these if properly set (no undefined to allow overriding with spread)\n ...(typeof suspendUntilReady === 'boolean' && { suspendUntilReady }),\n ...(typeof suspendWhileReconciling === 'boolean' && { suspendWhileReconciling }),\n ...(typeof updateOnContextChanged === 'boolean' && { updateOnContextChanged }),\n ...(typeof updateOnConfigurationChanged === 'boolean' && { updateOnConfigurationChanged }),\n };\n};\n", "import type { Client, Provider } from '@openfeature/web-sdk';\nimport { NOOP_PROVIDER, ProviderEvents } from '@openfeature/web-sdk';\nimport { use } from './use';\n\n/**\n * A weak map is used to store the global suspense status for each provider. It's\n * important for this to be global to avoid rerender loops. Using useRef won't\n * work because the value isn't preserved when a promise is thrown in a component,\n * which is how suspense operates.\n */\nconst globalProviderSuspenseStatus = new WeakMap<Provider, Promise<unknown>>();\n\n/**\n * Suspends until the client is ready to evaluate feature flags.\n *\n * **DO NOT EXPORT PUBLICLY**\n * @internal\n * @param {Provider} provider the provider to suspend for\n * @param {Client} client the client to check for readiness\n */\nexport function suspendUntilInitialized(provider: Provider, client: Client) {\n const statusPromiseRef = globalProviderSuspenseStatus.get(provider);\n if (!statusPromiseRef) {\n // Noop provider is never ready, so we resolve immediately\n const statusPromise = provider !== NOOP_PROVIDER ? isProviderReady(client) : Promise.resolve();\n globalProviderSuspenseStatus.set(provider, statusPromise);\n // Use will throw the promise and React will trigger a rerender when it's resolved\n use(statusPromise);\n } else {\n // Reuse the existing promise, use won't rethrow if the promise has settled.\n use(statusPromiseRef);\n }\n}\n\n/**\n * Suspends until the provider has finished reconciling.\n *\n * **DO NOT EXPORT PUBLICLY**\n * @internal\n * @param {Client} client the client to check for readiness\n */\nexport function suspendUntilReconciled(client: Client) {\n use(isProviderReady(client));\n}\n\nasync function isProviderReady(client: Client) {\n const controller = new AbortController();\n try {\n return await new Promise((resolve, reject) => {\n client.addHandler(ProviderEvents.Ready, resolve, { signal: controller.signal });\n client.addHandler(ProviderEvents.Error, reject, { signal: controller.signal });\n });\n } finally {\n controller.abort();\n }\n}\n", "/// <reference types=\"react/experimental\" />\n// This function is adopted from https://github.com/vercel/swr\nimport React from 'react';\n\n/**\n * Extends a Promise-like value to include status tracking.\n * The extra properties are used to manage the lifecycle of the Promise, indicating its current state.\n * More information can be found in the React RFE for the use hook.\n * @see https://github.com/reactjs/rfcs/pull/229\n */\nexport type UsePromise<T> = Promise<T> & {\n status?: 'pending' | 'fulfilled' | 'rejected';\n value?: T;\n reason?: unknown;\n};\n\n/**\n * React.use is a React API that lets you read the value of a resource like a Promise or context.\n * It was officially added in React 19, so needs to be polyfilled to support older React versions.\n * @param {UsePromise} thenable A thenable object that represents a Promise-like value.\n * @returns {unknown} The resolved value of the thenable or throws if it's still pending or rejected.\n */\nexport const use =\n React.use ||\n // This extra generic is to avoid TypeScript mixing up the generic and JSX syntax\n // and emitting an error.\n // We assume that this is only for the `use(thenable)` case, not `use(context)`.\n // https://github.com/facebook/react/blob/aed00dacfb79d17c53218404c52b1c7aa59c4a89/packages/react-server/src/ReactFizzThenable.js#L45\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n (<T, _>(thenable: UsePromise<T>): T => {\n switch (thenable.status) {\n case 'pending':\n throw thenable;\n case 'fulfilled':\n return thenable.value as T;\n case 'rejected':\n throw thenable.reason;\n default:\n thenable.status = 'pending';\n thenable.then(\n (v) => {\n thenable.status = 'fulfilled';\n thenable.value = v;\n },\n (e) => {\n thenable.status = 'rejected';\n thenable.reason = e;\n },\n );\n throw thenable;\n }\n });\n", "import React from 'react';\nimport { Context } from '../internal';\nimport { type Client } from '@openfeature/web-sdk';\nimport { MissingContextError } from '../internal/errors';\n\n/**\n * Get the {@link Client} instance for this OpenFeatureProvider context.\n * Note that the provider to which this is bound is determined by the OpenFeatureProvider's domain.\n * @returns {Client} client for this scope\n */\nexport function useOpenFeatureClient(): Client {\n const { client } = React.useContext(Context) || {};\n\n if (!client) {\n throw new MissingContextError('No OpenFeature client available');\n }\n\n return client;\n}\n", "const context = 'Components using OpenFeature must be wrapped with an <OpenFeatureProvider>.';\nconst tip =\n 'If you are seeing this in a test, see: https://openfeature.dev/docs/reference/technologies/client/web/react#testing';\n\nexport class MissingContextError extends Error {\n constructor(reason: string) {\n super(`${reason}: ${context} ${tip}`);\n this.name = 'MissingContextError';\n }\n}\n", "import { useEffect, useState } from 'react';\nimport { useOpenFeatureClient } from './use-open-feature-client';\nimport type { ProviderStatus } from '@openfeature/web-sdk';\nimport { ProviderEvents } from '@openfeature/web-sdk';\n\n/**\n * Get the {@link ProviderStatus} for the OpenFeatureClient.\n * Reacts to changes in provider status.\n * @returns {ProviderStatus} status of the client for this scope\n */\nexport function useOpenFeatureClientStatus(): ProviderStatus {\n const client = useOpenFeatureClient();\n const [status, setStatus] = useState<ProviderStatus>(client.providerStatus);\n\n useEffect(() => {\n const controller = new AbortController();\n const updateStatus = () => setStatus(client.providerStatus);\n client.addHandler(ProviderEvents.ConfigurationChanged, updateStatus, { signal: controller.signal });\n client.addHandler(ProviderEvents.ContextChanged, updateStatus, { signal: controller.signal });\n client.addHandler(ProviderEvents.Error, updateStatus, { signal: controller.signal });\n client.addHandler(ProviderEvents.Ready, updateStatus, { signal: controller.signal });\n client.addHandler(ProviderEvents.Stale, updateStatus, { signal: controller.signal });\n client.addHandler(ProviderEvents.Reconciling, updateStatus, { signal: controller.signal });\n return () => {\n controller.abort();\n };\n }, [client]);\n\n return status;\n}\n", "import React from 'react';\nimport { Context } from '../internal';\nimport { OpenFeature } from '@openfeature/web-sdk';\nimport type { Provider } from '@openfeature/web-sdk';\nimport { MissingContextError } from '../internal/errors';\n\n/**\n * Get the {@link Provider} bound to the domain specified in the OpenFeatureProvider context.\n * Note that it isn't recommended to interact with the provider directly, but rather through\n * an OpenFeature client.\n * @returns {Provider} provider for this scope\n */\nexport function useOpenFeatureProvider(): Provider {\n const openFeatureContext = React.useContext(Context);\n\n if (!openFeatureContext) {\n throw new MissingContextError('No OpenFeature context available');\n }\n\n return OpenFeature.getProvider(openFeatureContext.client.metadata.domain);\n}\n", "import type { EvaluationDetails, FlagValue } from '@openfeature/web-sdk';\nimport { StandardResolutionReasons } from '@openfeature/web-sdk';\nimport type { FlagQuery } from '../query';\n\n// FlagQuery implementation, do not export\nexport class HookFlagQuery<T extends FlagValue = FlagValue> implements FlagQuery {\n constructor(private _details: EvaluationDetails<T>) {}\n\n get details() {\n return this._details;\n }\n\n get value() {\n return this._details?.value;\n }\n\n get variant() {\n return this._details.variant;\n }\n\n get flagMetadata() {\n return this._details.flagMetadata;\n }\n\n get reason() {\n return this._details.reason;\n }\n\n get isError() {\n return !!this._details?.errorCode || this._details.reason == StandardResolutionReasons.ERROR;\n }\n\n get errorCode() {\n return this._details?.errorCode;\n }\n\n get errorMessage() {\n return this._details?.errorMessage;\n }\n\n get isAuthoritative() {\n return (\n !this.isError &&\n this._details.reason != StandardResolutionReasons.STALE &&\n this._details.reason != StandardResolutionReasons.DISABLED\n );\n }\n\n get type() {\n return typeof this._details.value;\n }\n}\n", "import type { Client } from '@openfeature/web-sdk';\nimport { OpenFeature } from '@openfeature/web-sdk';\nimport * as React from 'react';\nimport type { ReactFlagEvaluationOptions } from '../options';\nimport { Context } from '../internal';\n\ntype ClientOrDomain =\n | {\n /**\n * An identifier which logically binds clients with providers\n * @see OpenFeature.setProvider() and overloads.\n */\n domain?: string;\n client?: never;\n }\n | {\n /**\n * OpenFeature client to use.\n */\n client?: Client;\n domain?: never;\n };\n\ntype ProviderProps = {\n children?: React.ReactNode;\n} & ClientOrDomain &\n ReactFlagEvaluationOptions;\n\n/**\n * Provides a scope for evaluating feature flags by binding a client to all child components.\n * @param {ProviderProps} properties props for the context provider\n * @returns {OpenFeatureProvider} context provider\n */\nexport function OpenFeatureProvider({ client, domain, children, ...options }: ProviderProps) {\n const stableClient = React.useMemo(() => client || OpenFeature.getClient(domain), [client, domain]);\n\n return <Context.Provider value={{ client: stableClient, options }}>{children}</Context.Provider>;\n}\n", "import { ProviderStatus } from '@openfeature/web-sdk';\nimport { useOpenFeatureClient } from './use-open-feature-client';\nimport { useOpenFeatureClientStatus } from './use-open-feature-client-status';\nimport type { ReactFlagEvaluationOptions } from '../options';\nimport { DEFAULT_OPTIONS, useProviderOptions, normalizeOptions, suspendUntilInitialized } from '../internal';\nimport { useOpenFeatureProvider } from './use-open-feature-provider';\n\ntype Options = Pick<ReactFlagEvaluationOptions, 'suspendUntilReady'>;\n\n/**\n * Utility hook that triggers suspense until the provider is {@link ProviderStatus.READY}, without evaluating any flags.\n * Especially useful for React v16/17 \"Legacy Suspense\", in which siblings to suspending components are\n * initially mounted and then hidden (see: https://github.com/reactwg/react-18/discussions/7).\n *\n * NOTE: This hook returns true only when the provider status is {@link ProviderStatus.READY}.\n * For other statuses (ERROR, STALE, FATAL, RECONCILING), use {@link useOpenFeatureClientStatus}.\n * @param {Options} options options for suspense\n * @returns {boolean} boolean indicating if provider is {@link ProviderStatus.READY}, useful if suspense is disabled and you want to handle loaders on your own\n */\nexport function useWhenProviderReady(options?: Options): boolean {\n // highest priority > evaluation hook options > provider options > default options > lowest priority\n const defaultedOptions = { ...DEFAULT_OPTIONS, ...useProviderOptions(), ...normalizeOptions(options) };\n const client = useOpenFeatureClient();\n const status = useOpenFeatureClientStatus();\n const provider = useOpenFeatureProvider();\n\n if (defaultedOptions.suspendUntilReady && status === ProviderStatus.NOT_READY) {\n suspendUntilInitialized(provider, client);\n }\n\n return status === ProviderStatus.READY;\n}\n", "import type { JsonValue, Provider } from '@openfeature/web-sdk';\nimport { InMemoryProvider, NOOP_PROVIDER, OpenFeature } from '@openfeature/web-sdk';\nimport React from 'react';\nimport type { NormalizedOptions } from '../options';\nimport { OpenFeatureProvider } from './provider';\n\ntype FlagValueMap = { [flagKey: string]: JsonValue };\ntype FlagConfig = ConstructorParameters<typeof InMemoryProvider>[0];\ntype TestProviderProps = Omit<React.ComponentProps<typeof OpenFeatureProvider>, 'client'> &\n (\n | {\n provider?: never;\n /**\n * Optional map of flagKeys to flagValues for this OpenFeatureTestProvider context.\n * If not supplied, all flag evaluations will default.\n */\n flagValueMap?: FlagValueMap;\n /**\n * Optional delay for the underlying test provider's readiness and reconciliation.\n * Defaults to 0.\n */\n delayMs?: number;\n }\n | {\n /**\n * An optional partial provider to pass for full control over the flag resolution for this OpenFeatureTestProvider context.\n * Any un-implemented methods or properties will no-op.\n */\n provider?: Partial<Provider>;\n flagValueMap?: never;\n delayMs?: never;\n }\n );\n\nconst TEST_VARIANT = 'test-variant';\nconst TEST_PROVIDER = 'test-provider';\n\n// internal provider which is basically the in-memory provider with a simpler config and some optional fake delays\nclass TestProvider extends InMemoryProvider {\n // initially make this undefined, we still set it if a delay is specified\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore - For maximum compatibility with previous versions, we ignore a possible TS error here,\n // since \"initialize\" was previously defined in superclass.\n // We can safely remove this ts-ignore in a few versions\n initialize: Provider['initialize'] = undefined;\n\n // \"place-holder\" init function which we only assign if want a delay\n private delayedInitialize = async () => {\n await new Promise<void>((resolve) => setTimeout(resolve, this.delay));\n };\n\n constructor(\n flagValueMap: FlagValueMap,\n private delay = 0,\n ) {\n // convert the simple flagValueMap into an in-memory config\n const flagConfig = Object.entries(flagValueMap).reduce((acc: FlagConfig, flag): FlagConfig => {\n return {\n ...acc,\n [flag[0]]: {\n variants: {\n [TEST_VARIANT]: flag[1],\n },\n defaultVariant: TEST_VARIANT,\n disabled: false,\n },\n };\n }, {});\n super(flagConfig);\n // only define and init if there's a non-zero delay specified\n this.initialize = this.delay ? this.delayedInitialize.bind(this) : undefined;\n }\n\n async onContextChange() {\n return new Promise<void>((resolve) => setTimeout(resolve, this.delay));\n }\n}\n\n/**\n * A React Context provider based on the {@link InMemoryProvider}, specifically built for testing.\n * Use this for testing components that use flag evaluation hooks.\n * @param {TestProviderProps} testProviderOptions options for the OpenFeatureTestProvider\n * @returns {OpenFeatureProvider} OpenFeatureTestProvider\n */\nexport function OpenFeatureTestProvider(testProviderOptions: TestProviderProps) {\n const { flagValueMap, provider } = testProviderOptions;\n const effectiveProvider = (\n flagValueMap ? new TestProvider(flagValueMap, testProviderOptions.delayMs) : mixInNoop(provider) || NOOP_PROVIDER\n ) as Provider;\n testProviderOptions.domain\n ? OpenFeature.setProvider(testProviderOptions.domain, effectiveProvider)\n : OpenFeature.setProvider(effectiveProvider);\n\n return (\n <OpenFeatureProvider {...(testProviderOptions as NormalizedOptions)} domain={testProviderOptions.domain}>\n {testProviderOptions.children}\n </OpenFeatureProvider>\n );\n}\n\n// mix in the no-op provider when the partial is passed\nfunction mixInNoop(provider: Partial<Provider> = {}) {\n // fill in any missing methods with no-ops\n for (const prop of Object.getOwnPropertyNames(Object.getPrototypeOf(NOOP_PROVIDER)).filter(\n (prop) => prop !== 'constructor',\n )) {\n const patchedProvider = provider as { [key: string]: keyof Provider };\n if (!Object.getPrototypeOf(patchedProvider)[prop] && !patchedProvider[prop]) {\n patchedProvider[prop] = Object.getPrototypeOf(NOOP_PROVIDER)[prop];\n }\n }\n // fill in the metadata if missing\n if (!provider.metadata || !provider.metadata.name) {\n (provider.metadata as unknown) = { name: TEST_PROVIDER };\n }\n return provider;\n}\n", "import { useCallback, useContext, useEffect, useState } from 'react';\nimport type { EvaluationContext } from '@openfeature/web-sdk';\nimport { OpenFeature } from '@openfeature/web-sdk';\nimport { Context } from '../internal';\n\nexport type ContextMutationOptions = {\n /**\n * Mutate the default context instead of the domain scoped context applied at the `<OpenFeatureProvider/>`.\n * By default, will use the domain set on `<OpenFeatureProvider/>` (or the domain associated with the client set on `<OpenFeatureProvider/>`).\n * See the {@link https://openfeature.dev/docs/reference/technologies/client/web/#manage-evaluation-context-for-domains|documentation} for more information.\n * @default false\n */\n defaultContext?: boolean;\n};\n\nexport type ContextMutation = {\n /**\n * Context-aware function to set the desired context (see: {@link ContextMutationOptions} for details).\n * There's generally no need to await the result of this function; flag evaluation hooks will re-render when the context is updated.\n * This promise never rejects.\n * @param updatedContext New context object or method to generate it from the current context\n * @returns Promise for awaiting the context update\n */\n setContext: (\n updatedContext: EvaluationContext | ((currentContext: EvaluationContext) => EvaluationContext),\n ) => Promise<void>;\n};\n\n/**\n * Get context-aware tracking function(s) for mutating the evaluation context associated with this domain, or the default context if `defaultContext: true`.\n * See the {@link https://openfeature.dev/docs/reference/technologies/client/web/#targeting-and-context|documentation} for more information.\n * @param {ContextMutationOptions} options options for the generated function\n * @returns {ContextMutation} context-aware function(s) to mutate evaluation context\n */\nexport function useContextMutator(options: ContextMutationOptions = { defaultContext: false }): ContextMutation {\n const { client } = useContext(Context) || {};\n const domain = client?.metadata.domain;\n\n // TODO: Replace this warning with a thrown error in a future major release,\n // to match the behavior of `useOpenFeatureProvider` + `useOpenFeatureClient`,\n // when `defaultContext` isn't explicitly set to true.\n const [warned, setWarned] = useState(false);\n useEffect(() => {\n if (options.defaultContext || domain) {\n if (warned) {\n setWarned(false);\n }\n return;\n }\n\n if (!warned) {\n console.warn(\n '[useContextMutator] No domain available from OpenFeature context; are you using <OpenFeatureProvider/>? setContext will mutate the default context, as if `defaultContext: true` were set. This may result in a thrown error in the future.',\n );\n setWarned(true);\n }\n }, [warned]);\n\n const setContext = useCallback(\n async (\n updatedContext: EvaluationContext | ((currentContext: EvaluationContext) => EvaluationContext),\n ): Promise<void> => {\n const previousContext = OpenFeature.getContext(options?.defaultContext ? undefined : domain);\n const resolvedContext = typeof updatedContext === 'function' ? updatedContext(previousContext) : updatedContext;\n\n if (previousContext !== resolvedContext) {\n if (!domain || options?.defaultContext) {\n await OpenFeature.setContext(resolvedContext);\n } else {\n await OpenFeature.setContext(domain, resolvedContext);\n }\n }\n },\n [domain, options?.defaultContext],\n );\n\n return {\n setContext,\n };\n}\n", "import type { Tracking, TrackingEventDetails } from '@openfeature/web-sdk';\nimport { useCallback } from 'react';\nimport { useOpenFeatureClient } from '../provider';\n\nexport type Track = {\n /**\n * Context-aware tracking function for the parent `<OpenFeatureProvider/>`.\n * Track a user action or application state, usually representing a business objective or outcome.\n * @param trackingEventName an identifier for the event\n * @param trackingEventDetails the details of the tracking event\n */\n track: Tracking['track'];\n};\n\n/**\n * Get a context-aware tracking function.\n * @returns {Track} context-aware tracking\n */\nexport function useTrack(): Track {\n const client = useOpenFeatureClient();\n\n const track = useCallback((trackingEventName: string, trackingEventDetails?: TrackingEventDetails) => {\n client.track(trackingEventName, trackingEventDetails);\n }, []);\n\n return {\n track,\n };\n}\n", "export * from './declarative';\nexport * from './evaluation';\nexport * from './query';\nexport * from './provider';\nexport * from './context';\nexport * from './tracking';\nexport * from './options';\n// re-export the web-sdk so consumers can access that API from the react-sdk\nexport * from '@openfeature/web-sdk';\n"],
5
- "mappings": "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",
3
+ "sources": ["../../src/declarative/FeatureFlag.tsx", "../../src/evaluation/use-feature-flag.ts", "../../src/internal/context.ts", "../../src/internal/is-equal.ts", "../../src/internal/options.ts", "../../src/internal/suspense.ts", "../../src/internal/use.ts", "../../src/provider/use-open-feature-client.ts", "../../src/internal/errors.ts", "../../src/provider/use-open-feature-client-status.ts", "../../src/provider/use-open-feature-provider.ts", "../../src/internal/hook-flag-query.ts", "../../../shared/src/client/framework-metadata.ts", "../../src/provider/provider.tsx", "../../src/provider/use-when-provider-ready.ts", "../../src/provider/test-provider.tsx", "../../src/context/use-context-mutator.ts", "../../src/tracking/use-track.ts", "../../src/index.ts"],
4
+ "sourcesContent": ["import React from 'react';\nimport { useFlag } from '../evaluation';\nimport type { FlagQuery } from '../query';\nimport type { FlagValue, EvaluationDetails, ConstrainedFlagKey } from '@openfeature/web-sdk';\nimport { isEqual } from '../internal';\nimport type { ReactFlagEvaluationOptions } from '../options';\n\n/**\n * Default predicate function that checks if the expected value equals the actual flag value.\n * @param {T} expected The expected value to match against\n * @param {EvaluationDetails<T>} actual The evaluation details containing the actual flag value\n * @returns {boolean} true if the values match, false otherwise\n */\nfunction equals<T extends FlagValue>(expected: T, actual: EvaluationDetails<T>): boolean {\n return isEqual(expected, actual.value);\n}\n\n/**\n * Props for the FeatureFlag component that conditionally renders content based on feature flag state.\n * @interface FeatureFlagProps\n */\ninterface FeatureFlagProps<T extends FlagValue = FlagValue> {\n /**\n * The key of the feature flag to evaluate.\n */\n flagKey: ConstrainedFlagKey<T>;\n\n /**\n * Optional predicate function for custom matching logic.\n * If provided, this function will be used instead of the default equality check.\n * @param matchValue The value to match (matchValue prop)\n * @param details The evaluation details\n * @returns true if the condition is met, false otherwise\n */\n predicate?: (matchValue: T | undefined, details: EvaluationDetails<T>) => boolean;\n\n /**\n * Content to render when the feature flag condition is met.\n * Can be a React node or a function that receives flag query details and returns a React node.\n */\n children: React.ReactNode | ((details: FlagQuery<T>) => React.ReactNode);\n\n /**\n * Optional content to render when the feature flag condition is not met.\n * Can be a React node or a function that receives evaluation details and returns a React node.\n */\n fallback?: React.ReactNode | ((details: EvaluationDetails<T>) => React.ReactNode);\n\n /**\n * Flag evaluation options that will be passed to useFlag hook.\n */\n evaluationOptions?: ReactFlagEvaluationOptions;\n}\n\n/**\n * Configuration for matching flag values.\n * For boolean flags, `match` is optional (defaults to checking truthiness).\n * For non-boolean flags (string, number, object), `match` is required to determine when to render.\n */\ntype FeatureFlagMatchConfig<T extends FlagValue> = {\n /**\n * Default value to use when the feature flag is not found.\n */\n defaultValue: T;\n} & (T extends boolean\n ? {\n /**\n * Optional value to match against the feature flag value.\n */\n matchValue?: T | undefined;\n }\n : {\n /**\n * Value to match against the feature flag value.\n * Required for non-boolean flags to determine when children should render.\n * By default, strict equality is used for comparison.\n */\n matchValue: T;\n });\n\ntype FeatureFlagComponentProps<T extends FlagValue> = FeatureFlagProps<T> & FeatureFlagMatchConfig<T>;\n\n/**\n * @experimental This API is experimental, and is subject to change.\n * FeatureFlag component that conditionally renders its children based on the evaluation of a feature flag.\n * @param {FeatureFlagComponentProps} props The properties for the FeatureFlag component.\n * @returns {React.ReactElement | null} The rendered component or null if the feature is not enabled.\n */\nexport function FeatureFlag<T extends FlagValue = FlagValue>({\n flagKey,\n matchValue,\n predicate,\n defaultValue,\n children,\n evaluationOptions = {},\n fallback = null,\n}: FeatureFlagComponentProps<T>): React.ReactElement | null {\n const details = useFlag(flagKey, defaultValue, {\n updateOnContextChanged: true,\n ...evaluationOptions,\n });\n\n // If the flag evaluation failed, we render the fallback\n if (details.reason === 'ERROR') {\n const fallbackNode: React.ReactNode =\n typeof fallback === 'function' ? fallback(details.details as EvaluationDetails<T>) : fallback;\n return <>{fallbackNode}</>;\n }\n\n // Use custom predicate if provided, otherwise use default matching logic\n let shouldRender = false;\n if (predicate) {\n shouldRender = predicate(matchValue as T, details.details as EvaluationDetails<T>);\n } else if (matchValue !== undefined) {\n // Default behavior: check if match value equals flag value\n shouldRender = equals(matchValue, details.details as EvaluationDetails<T>);\n } else if (details.type === 'boolean') {\n // If no match value is provided, render if flag is truthy\n shouldRender = Boolean(details.value);\n } else {\n shouldRender = false;\n }\n\n if (shouldRender) {\n const childNode: React.ReactNode = typeof children === 'function' ? children(details as FlagQuery<T>) : children;\n return <>{childNode}</>;\n }\n\n const fallbackNode: React.ReactNode =\n typeof fallback === 'function' ? fallback(details.details as EvaluationDetails<T>) : fallback;\n return <>{fallbackNode}</>;\n}\n", "import type {\n BooleanFlagKey,\n Client,\n ClientProviderEvents,\n ConstrainedFlagKey,\n EvaluationDetails,\n EventHandler,\n FlagEvaluationOptions,\n FlagValue,\n JsonValue,\n NumberFlagKey,\n ObjectFlagKey,\n StringFlagKey,\n} from '@openfeature/web-sdk';\nimport { ProviderEvents, ProviderStatus } from '@openfeature/web-sdk';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport {\n DEFAULT_OPTIONS,\n isEqual,\n normalizeOptions,\n suspendUntilInitialized,\n suspendUntilReconciled,\n useProviderOptions,\n} from '../internal';\nimport type { ReactFlagEvaluationNoSuspenseOptions, ReactFlagEvaluationOptions } from '../options';\nimport { useOpenFeatureClient } from '../provider/use-open-feature-client';\nimport { useOpenFeatureClientStatus } from '../provider/use-open-feature-client-status';\nimport { useOpenFeatureProvider } from '../provider/use-open-feature-provider';\nimport type { FlagQuery } from '../query';\nimport { HookFlagQuery } from '../internal/hook-flag-query';\n\n// This type is a bit wild-looking, but I think we need it.\n// We have to use the conditional, because otherwise useFlag('key', false) would return false, not boolean (too constrained).\n// We have a duplicate for the hook return below, this one is just used for casting because the name isn't as clear\ntype ConstrainedFlagQuery<T> = FlagQuery<\n T extends boolean\n ? boolean\n : T extends number\n ? number\n : T extends string\n ? string\n : T extends JsonValue\n ? T\n : JsonValue\n>;\n\n/**\n * Evaluates a feature flag generically, returning an react-flavored queryable object.\n * The resolver method to use is based on the type of the defaultValue.\n * For type-specific hooks, use {@link useBooleanFlagValue}, {@link useBooleanFlagDetails} and equivalents.\n * By default, components will re-render when the flag value changes.\n * @param {ConstrainedFlagKey<T>} flagKey the flag identifier\n * @template {FlagValue} T A optional generic argument constraining the default.\n * @param {T} defaultValue the default value; used to determine what resolved type should be used.\n * @param {ReactFlagEvaluationOptions} options for this evaluation\n * @returns { FlagQuery } a queryable object containing useful information about the flag.\n */\nexport function useFlag<T extends FlagValue = FlagValue>(\n flagKey: ConstrainedFlagKey<T>,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): FlagQuery<\n T extends boolean\n ? boolean\n : T extends number\n ? number\n : T extends string\n ? string\n : T extends JsonValue\n ? T\n : JsonValue\n> {\n // use the default value to determine the resolver to call\n const query =\n typeof defaultValue === 'boolean'\n ? new HookFlagQuery<boolean>(useBooleanFlagDetails(flagKey, defaultValue, options))\n : typeof defaultValue === 'number'\n ? new HookFlagQuery<number>(useNumberFlagDetails(flagKey, defaultValue, options))\n : typeof defaultValue === 'string'\n ? new HookFlagQuery<string>(useStringFlagDetails(flagKey, defaultValue, options))\n : new HookFlagQuery<JsonValue>(useObjectFlagDetails(flagKey, defaultValue, options));\n // TS sees this as HookFlagQuery<JsonValue>, because the compiler isn't aware of the `typeof` checks above.\n return query as unknown as ConstrainedFlagQuery<T>;\n}\n\n// alias to the return value of useFlag, used to keep useSuspenseFlag consistent\ntype UseFlagReturn<T extends FlagValue> = ReturnType<typeof useFlag<T>>;\n\n/**\n * Equivalent to {@link useFlag} with `options: { suspend: true }`\n * @experimental Suspense is an experimental feature subject to change in future versions.\n * @param {ConstrainedFlagKey<T>} flagKey the flag identifier\n * @template {FlagValue} T A optional generic argument constraining the default.\n * @param {T} defaultValue the default value; used to determine what resolved type should be used.\n * @param {ReactFlagEvaluationNoSuspenseOptions} options for this evaluation\n * @returns { UseFlagReturn<T> } a queryable object containing useful information about the flag.\n */\nexport function useSuspenseFlag<T extends FlagValue = FlagValue>(\n flagKey: ConstrainedFlagKey<T>,\n defaultValue: T,\n options?: ReactFlagEvaluationNoSuspenseOptions,\n): UseFlagReturn<T> {\n return useFlag(flagKey, defaultValue, { ...options, suspendUntilReady: true, suspendWhileReconciling: true });\n}\n\n/**\n * Evaluates a feature flag, returning a boolean.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {BooleanFlagKey} flagKey the flag identifier\n * @param {boolean} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { boolean} a EvaluationDetails object for this evaluation\n */\nexport function useBooleanFlagValue(\n flagKey: BooleanFlagKey,\n defaultValue: boolean,\n options?: ReactFlagEvaluationOptions,\n): boolean {\n return useBooleanFlagDetails(flagKey, defaultValue, options).value;\n}\n\n/**\n * Evaluates a feature flag, returning evaluation details.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {BooleanFlagKey} flagKey the flag identifier\n * @param {boolean} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { EvaluationDetails<boolean>} a EvaluationDetails object for this evaluation\n */\nexport function useBooleanFlagDetails(\n flagKey: BooleanFlagKey,\n defaultValue: boolean,\n options?: ReactFlagEvaluationOptions,\n): EvaluationDetails<boolean> {\n return attachHandlersAndResolve(\n flagKey,\n defaultValue,\n (client) => {\n return client.getBooleanDetails;\n },\n options,\n );\n}\n\n/**\n * Evaluates a feature flag, returning a string.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {StringFlagKey} flagKey the flag identifier\n * @template {string} [T=string] A optional generic argument constraining the string\n * @param {T} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { boolean} a EvaluationDetails object for this evaluation\n */\nexport function useStringFlagValue<T extends string = string>(\n flagKey: StringFlagKey,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): string {\n return useStringFlagDetails(flagKey, defaultValue, options).value;\n}\n\n/**\n * Evaluates a feature flag, returning evaluation details.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {StringFlagKey} flagKey the flag identifier\n * @template {string} [T=string] A optional generic argument constraining the string\n * @param {T} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { EvaluationDetails<string>} a EvaluationDetails object for this evaluation\n */\nexport function useStringFlagDetails<T extends string = string>(\n flagKey: StringFlagKey,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): EvaluationDetails<string> {\n return attachHandlersAndResolve(\n flagKey,\n defaultValue,\n (client) => {\n return client.getStringDetails<T>;\n },\n options,\n );\n}\n\n/**\n * Evaluates a feature flag, returning a number.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {NumberFlagKey} flagKey the flag identifier\n * @template {number} [T=number] A optional generic argument constraining the number\n * @param {T} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { boolean} a EvaluationDetails object for this evaluation\n */\nexport function useNumberFlagValue<T extends number = number>(\n flagKey: NumberFlagKey,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): number {\n return useNumberFlagDetails(flagKey, defaultValue, options).value;\n}\n\n/**\n * Evaluates a feature flag, returning evaluation details.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {NumberFlagKey} flagKey the flag identifier\n * @template {number} [T=number] A optional generic argument constraining the number\n * @param {T} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { EvaluationDetails<number>} a EvaluationDetails object for this evaluation\n */\nexport function useNumberFlagDetails<T extends number = number>(\n flagKey: NumberFlagKey,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): EvaluationDetails<number> {\n return attachHandlersAndResolve(\n flagKey,\n defaultValue,\n (client) => {\n return client.getNumberDetails<T>;\n },\n options,\n );\n}\n\n/**\n * Evaluates a feature flag, returning an object.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {ObjectFlagKey} flagKey the flag identifier\n * @template {JsonValue} [T=JsonValue] A optional generic argument describing the structure\n * @param {T} defaultValue the default value\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { boolean} a EvaluationDetails object for this evaluation\n */\nexport function useObjectFlagValue<T extends JsonValue = JsonValue>(\n flagKey: ObjectFlagKey,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): T {\n return useObjectFlagDetails<T>(flagKey, defaultValue, options).value;\n}\n\n/**\n * Evaluates a feature flag, returning evaluation details.\n * By default, components will re-render when the flag value changes.\n * For a generic hook returning a queryable interface, see {@link useFlag}.\n * @param {ObjectFlagKey} flagKey the flag identifier\n * @param {T} defaultValue the default value\n * @template {JsonValue} [T=JsonValue] A optional generic argument describing the structure\n * @param {ReactFlagEvaluationOptions} options options for this evaluation\n * @returns { EvaluationDetails<T>} a EvaluationDetails object for this evaluation\n */\nexport function useObjectFlagDetails<T extends JsonValue = JsonValue>(\n flagKey: ObjectFlagKey,\n defaultValue: T,\n options?: ReactFlagEvaluationOptions,\n): EvaluationDetails<T> {\n return attachHandlersAndResolve(\n flagKey,\n defaultValue,\n (client) => {\n return client.getObjectDetails<T>;\n },\n options,\n );\n}\n\n// determines if a flag should be re-evaluated based on a list of changed flags\nfunction shouldEvaluateFlag(flagKey: string, flagsChanged?: string[]): boolean {\n // if flagsChange is missing entirely, we don't know what to re-render\n return !flagsChanged || flagsChanged.includes(flagKey);\n}\n\nfunction attachHandlersAndResolve<T extends FlagValue>(\n flagKey: string,\n defaultValue: T,\n resolver: (\n client: Client,\n ) => (flagKey: string, defaultValue: T, options?: FlagEvaluationOptions) => EvaluationDetails<T>,\n options?: ReactFlagEvaluationOptions,\n): EvaluationDetails<T> {\n // highest priority > evaluation hook options > provider options > default options > lowest priority\n const defaultedOptions = { ...DEFAULT_OPTIONS, ...useProviderOptions(), ...normalizeOptions(options) };\n const client = useOpenFeatureClient();\n const status = useOpenFeatureClientStatus();\n const provider = useOpenFeatureProvider();\n const isFirstRender = useRef(true);\n\n if (defaultedOptions.suspendUntilReady && status === ProviderStatus.NOT_READY) {\n suspendUntilInitialized(provider, client);\n }\n\n if (defaultedOptions.suspendWhileReconciling && status === ProviderStatus.RECONCILING) {\n suspendUntilReconciled(client);\n }\n\n const [evaluationDetails, setEvaluationDetails] = useState<EvaluationDetails<T>>(() =>\n resolver(client).call(client, flagKey, defaultValue, options),\n );\n\n // Re-evaluate when dependencies change (handles prop changes like flagKey), or if during a re-render, we have detected a change in the evaluated value\n useEffect(() => {\n if (isFirstRender.current) {\n isFirstRender.current = false;\n return;\n }\n\n const newDetails = resolver(client).call(client, flagKey, defaultValue, options);\n if (!isEqual(newDetails, evaluationDetails)) {\n setEvaluationDetails(newDetails);\n }\n }, [client, flagKey, defaultValue, options, resolver, evaluationDetails]);\n\n // Maintain a mutable reference to the evaluation details to have a up-to-date reference in the handlers.\n const evaluationDetailsRef = useRef<EvaluationDetails<T>>(evaluationDetails);\n useEffect(() => {\n evaluationDetailsRef.current = evaluationDetails;\n }, [evaluationDetails]);\n\n const updateEvaluationDetailsCallback = useCallback(() => {\n const updatedEvaluationDetails = resolver(client).call(client, flagKey, defaultValue, options);\n\n /**\n * Avoid re-rendering if the evaluation details haven't changed.\n */\n if (!isEqual(updatedEvaluationDetails, evaluationDetailsRef.current)) {\n setEvaluationDetails(updatedEvaluationDetails);\n }\n }, [client, flagKey, defaultValue, options, resolver]);\n\n const configurationChangeCallback = useCallback<EventHandler<ClientProviderEvents.ConfigurationChanged>>(\n (eventDetails) => {\n if (shouldEvaluateFlag(flagKey, eventDetails?.flagsChanged)) {\n updateEvaluationDetailsCallback();\n }\n },\n [flagKey, updateEvaluationDetailsCallback],\n );\n\n useEffect(() => {\n const controller = new AbortController();\n // Always register the Ready handler to catch provider initialization\n // even if current status is already READY (e.g., from a NoOp provider)\n client.addHandler(ProviderEvents.Ready, updateEvaluationDetailsCallback, { signal: controller.signal });\n\n if (defaultedOptions.updateOnContextChanged) {\n // update when the context changes\n client.addHandler(ProviderEvents.ContextChanged, updateEvaluationDetailsCallback, { signal: controller.signal });\n }\n\n if (defaultedOptions.updateOnConfigurationChanged) {\n // update when the provider configuration changes\n client.addHandler(ProviderEvents.ConfigurationChanged, configurationChangeCallback, {\n signal: controller.signal,\n });\n }\n return () => {\n // cleanup the handlers\n controller.abort();\n };\n }, [\n client,\n defaultedOptions.updateOnContextChanged,\n defaultedOptions.updateOnConfigurationChanged,\n updateEvaluationDetailsCallback,\n configurationChangeCallback,\n ]);\n\n return evaluationDetails;\n}\n", "import type { Client } from '@openfeature/web-sdk';\nimport React from 'react';\nimport type { NormalizedOptions, ReactFlagEvaluationOptions } from '../options';\nimport { normalizeOptions } from '.';\n\n/**\n * The underlying React context.\n *\n * **DO NOT EXPORT PUBLICLY**\n * @internal\n */\nexport const Context = React.createContext<{ client: Client; options: ReactFlagEvaluationOptions } | undefined>(\n undefined,\n);\n\n/**\n * Get a normalized copy of the options used for this OpenFeatureProvider, see {@link normalizeOptions}.\n *\n * **DO NOT EXPORT PUBLICLY**\n * @internal\n * @returns {NormalizedOptions} normalized options the defaulted options, not defaulted or normalized.\n */\nexport function useProviderOptions(): NormalizedOptions {\n const { options } = React.useContext(Context) || {};\n return normalizeOptions(options);\n}\n", "/**\n * Deeply compare two values to determine if they are equal.\n * Supports primitives and serializable objects.\n *\n * Note: Does not handle Date, RegExp, Map, Set, or circular references.\n * Suitable for comparing EvaluationDetails and other JSON-serializable data.\n * @param {unknown} value First value to compare\n * @param {unknown} other Second value to compare\n * @returns {boolean} True if the values are equal\n */\nexport function isEqual(value: unknown, other: unknown): boolean {\n if (value === other) {\n return true;\n }\n\n if (typeof value !== typeof other) {\n return false;\n }\n\n if (typeof value === 'object' && value !== null && typeof other === 'object' && other !== null) {\n const valueKeys = Object.keys(value);\n const otherKeys = Object.keys(other);\n\n if (valueKeys.length !== otherKeys.length) {\n return false;\n }\n\n for (const key of valueKeys) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (!isEqual((value as any)[key], (other as any)[key])) {\n return false;\n }\n }\n\n return true;\n }\n\n return false;\n}\n", "import type { ReactFlagEvaluationOptions, NormalizedOptions } from '../options';\n\n/**\n * Default options.\n * DO NOT EXPORT PUBLICLY\n * @internal\n */\nexport const DEFAULT_OPTIONS: ReactFlagEvaluationOptions = {\n updateOnContextChanged: true,\n updateOnConfigurationChanged: true,\n suspendUntilReady: false,\n suspendWhileReconciling: false,\n};\n\n/**\n * Returns normalization options (all `undefined` fields removed, and `suspend` decomposed to `suspendUntilReady` and `suspendWhileReconciling`).\n * DO NOT EXPORT PUBLICLY\n * @internal\n * @param {ReactFlagEvaluationOptions} options options to normalize\n * @returns {NormalizedOptions} normalized options\n */\nexport const normalizeOptions: (options?: ReactFlagEvaluationOptions) => NormalizedOptions = (\n options: ReactFlagEvaluationOptions = {},\n) => {\n const updateOnContextChanged = options.updateOnContextChanged;\n const updateOnConfigurationChanged = options.updateOnConfigurationChanged;\n\n // fall-back the suspense options to the catch-all `suspend` property\n const suspendUntilReady = 'suspendUntilReady' in options ? options.suspendUntilReady : options.suspend;\n const suspendWhileReconciling =\n 'suspendWhileReconciling' in options ? options.suspendWhileReconciling : options.suspend;\n\n return {\n // only return these if properly set (no undefined to allow overriding with spread)\n ...(typeof suspendUntilReady === 'boolean' && { suspendUntilReady }),\n ...(typeof suspendWhileReconciling === 'boolean' && { suspendWhileReconciling }),\n ...(typeof updateOnContextChanged === 'boolean' && { updateOnContextChanged }),\n ...(typeof updateOnConfigurationChanged === 'boolean' && { updateOnConfigurationChanged }),\n };\n};\n", "import type { Client, Provider } from '@openfeature/web-sdk';\nimport { NOOP_PROVIDER, ProviderEvents } from '@openfeature/web-sdk';\nimport { use } from './use';\n\n/**\n * A weak map is used to store the global suspense status for each provider. It's\n * important for this to be global to avoid rerender loops. Using useRef won't\n * work because the value isn't preserved when a promise is thrown in a component,\n * which is how suspense operates.\n */\nconst globalProviderSuspenseStatus = new WeakMap<Provider, Promise<unknown>>();\n\n/**\n * Suspends until the client is ready to evaluate feature flags.\n *\n * **DO NOT EXPORT PUBLICLY**\n * @internal\n * @param {Provider} provider the provider to suspend for\n * @param {Client} client the client to check for readiness\n */\nexport function suspendUntilInitialized(provider: Provider, client: Client) {\n const statusPromiseRef = globalProviderSuspenseStatus.get(provider);\n if (!statusPromiseRef) {\n // Noop provider is never ready, so we resolve immediately\n const statusPromise = provider !== NOOP_PROVIDER ? isProviderReady(client) : Promise.resolve();\n globalProviderSuspenseStatus.set(provider, statusPromise);\n // Use will throw the promise and React will trigger a rerender when it's resolved\n use(statusPromise);\n } else {\n // Reuse the existing promise, use won't rethrow if the promise has settled.\n use(statusPromiseRef);\n }\n}\n\n/**\n * Suspends until the provider has finished reconciling.\n *\n * **DO NOT EXPORT PUBLICLY**\n * @internal\n * @param {Client} client the client to check for readiness\n */\nexport function suspendUntilReconciled(client: Client) {\n use(isProviderReady(client));\n}\n\nasync function isProviderReady(client: Client) {\n const controller = new AbortController();\n try {\n return await new Promise((resolve, reject) => {\n client.addHandler(ProviderEvents.Ready, resolve, { signal: controller.signal });\n client.addHandler(ProviderEvents.Error, reject, { signal: controller.signal });\n });\n } finally {\n controller.abort();\n }\n}\n", "/// <reference types=\"react/experimental\" />\n// This function is adopted from https://github.com/vercel/swr\nimport React from 'react';\n\n/**\n * Extends a Promise-like value to include status tracking.\n * The extra properties are used to manage the lifecycle of the Promise, indicating its current state.\n * More information can be found in the React RFE for the use hook.\n * @see https://github.com/reactjs/rfcs/pull/229\n */\nexport type UsePromise<T> = Promise<T> & {\n status?: 'pending' | 'fulfilled' | 'rejected';\n value?: T;\n reason?: unknown;\n};\n\n/**\n * React.use is a React API that lets you read the value of a resource like a Promise or context.\n * It was officially added in React 19, so needs to be polyfilled to support older React versions.\n * @param {UsePromise} thenable A thenable object that represents a Promise-like value.\n * @returns {unknown} The resolved value of the thenable or throws if it's still pending or rejected.\n */\nexport const use =\n React.use ||\n // This extra generic is to avoid TypeScript mixing up the generic and JSX syntax\n // and emitting an error.\n // We assume that this is only for the `use(thenable)` case, not `use(context)`.\n // https://github.com/facebook/react/blob/aed00dacfb79d17c53218404c52b1c7aa59c4a89/packages/react-server/src/ReactFizzThenable.js#L45\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n (<T, _>(thenable: UsePromise<T>): T => {\n switch (thenable.status) {\n case 'pending':\n throw thenable;\n case 'fulfilled':\n return thenable.value as T;\n case 'rejected':\n throw thenable.reason;\n default:\n thenable.status = 'pending';\n thenable.then(\n (v) => {\n thenable.status = 'fulfilled';\n thenable.value = v;\n },\n (e) => {\n thenable.status = 'rejected';\n thenable.reason = e;\n },\n );\n throw thenable;\n }\n });\n", "import React from 'react';\nimport { Context } from '../internal';\nimport { type Client } from '@openfeature/web-sdk';\nimport { MissingContextError } from '../internal/errors';\n\n/**\n * Get the {@link Client} instance for this OpenFeatureProvider context.\n * Note that the provider to which this is bound is determined by the OpenFeatureProvider's domain.\n * @returns {Client} client for this scope\n */\nexport function useOpenFeatureClient(): Client {\n const { client } = React.useContext(Context) || {};\n\n if (!client) {\n throw new MissingContextError('No OpenFeature client available');\n }\n\n return client;\n}\n", "const context = 'Components using OpenFeature must be wrapped with an <OpenFeatureProvider>.';\nconst tip =\n 'If you are seeing this in a test, see: https://openfeature.dev/docs/reference/technologies/client/web/react#testing';\n\nexport class MissingContextError extends Error {\n constructor(reason: string) {\n super(`${reason}: ${context} ${tip}`);\n this.name = 'MissingContextError';\n }\n}\n", "import { useEffect, useState } from 'react';\nimport { useOpenFeatureClient } from './use-open-feature-client';\nimport type { ProviderStatus } from '@openfeature/web-sdk';\nimport { ProviderEvents } from '@openfeature/web-sdk';\n\n/**\n * Get the {@link ProviderStatus} for the OpenFeatureClient.\n * Reacts to changes in provider status.\n * @returns {ProviderStatus} status of the client for this scope\n */\nexport function useOpenFeatureClientStatus(): ProviderStatus {\n const client = useOpenFeatureClient();\n const [status, setStatus] = useState<ProviderStatus>(client.providerStatus);\n\n useEffect(() => {\n const controller = new AbortController();\n const updateStatus = () => setStatus(client.providerStatus);\n client.addHandler(ProviderEvents.ConfigurationChanged, updateStatus, { signal: controller.signal });\n client.addHandler(ProviderEvents.ContextChanged, updateStatus, { signal: controller.signal });\n client.addHandler(ProviderEvents.Error, updateStatus, { signal: controller.signal });\n client.addHandler(ProviderEvents.Ready, updateStatus, { signal: controller.signal });\n client.addHandler(ProviderEvents.Stale, updateStatus, { signal: controller.signal });\n client.addHandler(ProviderEvents.Reconciling, updateStatus, { signal: controller.signal });\n return () => {\n controller.abort();\n };\n }, [client]);\n\n return status;\n}\n", "import React from 'react';\nimport { Context } from '../internal';\nimport { OpenFeature } from '@openfeature/web-sdk';\nimport type { Provider } from '@openfeature/web-sdk';\nimport { MissingContextError } from '../internal/errors';\n\n/**\n * Get the {@link Provider} bound to the domain specified in the OpenFeatureProvider context.\n * Note that it isn't recommended to interact with the provider directly, but rather through\n * an OpenFeature client.\n * @returns {Provider} provider for this scope\n */\nexport function useOpenFeatureProvider(): Provider {\n const openFeatureContext = React.useContext(Context);\n\n if (!openFeatureContext) {\n throw new MissingContextError('No OpenFeature context available');\n }\n\n return OpenFeature.getProvider(openFeatureContext.client.metadata.domain);\n}\n", "import type { EvaluationDetails, FlagValue } from '@openfeature/web-sdk';\nimport { StandardResolutionReasons } from '@openfeature/web-sdk';\nimport type { FlagQuery } from '../query';\n\n// FlagQuery implementation, do not export\nexport class HookFlagQuery<T extends FlagValue = FlagValue> implements FlagQuery {\n constructor(private _details: EvaluationDetails<T>) {}\n\n get details() {\n return this._details;\n }\n\n get value() {\n return this._details?.value;\n }\n\n get variant() {\n return this._details.variant;\n }\n\n get flagMetadata() {\n return this._details.flagMetadata;\n }\n\n get reason() {\n return this._details.reason;\n }\n\n get isError() {\n return !!this._details?.errorCode || this._details.reason == StandardResolutionReasons.ERROR;\n }\n\n get errorCode() {\n return this._details?.errorCode;\n }\n\n get errorMessage() {\n return this._details?.errorMessage;\n }\n\n get isAuthoritative() {\n return (\n !this.isError &&\n this._details.reason != StandardResolutionReasons.STALE &&\n this._details.reason != StandardResolutionReasons.DISABLED\n );\n }\n\n get type() {\n return typeof this._details.value;\n }\n}\n", "import type { ClientMetadata, MetadataClient } from './client';\n\n/**\n * Wraps a client so framework metadata is visible through `metadata` and `this.metadata`.\n * @template T\n * @param {T} client client to wrap\n * @param {NonNullable<ClientMetadata['framework']>} framework framework metadata to expose\n * @returns {T} framework-aware client proxy\n */\nexport function withFrameworkMetadata<T extends MetadataClient>(\n client: T,\n framework: NonNullable<ClientMetadata['framework']>,\n): T {\n return new Proxy(client, {\n get(target, property, receiver) {\n if (property === 'metadata') {\n return {\n ...(Reflect.get(target, property, receiver) ?? {}),\n framework,\n };\n }\n\n const value = Reflect.get(target, property, receiver);\n\n if (typeof value !== 'function') {\n return value;\n }\n\n return (...args: unknown[]) => {\n const result = value.apply(receiver, args);\n return result === target ? receiver : result;\n };\n },\n });\n}\n", "import { withFrameworkMetadata } from '@openfeature/core';\nimport type { Client } from '@openfeature/web-sdk';\nimport { OpenFeature } from '@openfeature/web-sdk';\nimport * as React from 'react';\nimport type { ReactFlagEvaluationOptions } from '../options';\nimport { Context } from '../internal';\n\ntype ClientOrDomain =\n | {\n /**\n * An identifier which logically binds clients with providers\n * @see OpenFeature.setProvider() and overloads.\n */\n domain?: string;\n client?: never;\n }\n | {\n /**\n * OpenFeature client to use.\n */\n client?: Client;\n domain?: never;\n };\n\ntype ProviderProps = {\n children?: React.ReactNode;\n} & ClientOrDomain &\n ReactFlagEvaluationOptions;\n\n/**\n * Provides a scope for evaluating feature flags by binding a client to all child components.\n * @param {ProviderProps} properties props for the context provider\n * @returns {OpenFeatureProvider} context provider\n */\nexport function OpenFeatureProvider({ client, domain, children, ...options }: ProviderProps) {\n const stableClient = React.useMemo(\n () => withFrameworkMetadata(client || OpenFeature.getClient(domain), 'react'),\n [client, domain],\n );\n\n return <Context.Provider value={{ client: stableClient, options }}>{children}</Context.Provider>;\n}\n", "import { ProviderStatus } from '@openfeature/web-sdk';\nimport { useOpenFeatureClient } from './use-open-feature-client';\nimport { useOpenFeatureClientStatus } from './use-open-feature-client-status';\nimport type { ReactFlagEvaluationOptions } from '../options';\nimport { DEFAULT_OPTIONS, useProviderOptions, normalizeOptions, suspendUntilInitialized } from '../internal';\nimport { useOpenFeatureProvider } from './use-open-feature-provider';\n\ntype Options = Pick<ReactFlagEvaluationOptions, 'suspendUntilReady'>;\n\n/**\n * Utility hook that triggers suspense until the provider is {@link ProviderStatus.READY}, without evaluating any flags.\n * Especially useful for React v16/17 \"Legacy Suspense\", in which siblings to suspending components are\n * initially mounted and then hidden (see: https://github.com/reactwg/react-18/discussions/7).\n *\n * NOTE: This hook returns true only when the provider status is {@link ProviderStatus.READY}.\n * For other statuses (ERROR, STALE, FATAL, RECONCILING), use {@link useOpenFeatureClientStatus}.\n * @param {Options} options options for suspense\n * @returns {boolean} boolean indicating if provider is {@link ProviderStatus.READY}, useful if suspense is disabled and you want to handle loaders on your own\n */\nexport function useWhenProviderReady(options?: Options): boolean {\n // highest priority > evaluation hook options > provider options > default options > lowest priority\n const defaultedOptions = { ...DEFAULT_OPTIONS, ...useProviderOptions(), ...normalizeOptions(options) };\n const client = useOpenFeatureClient();\n const status = useOpenFeatureClientStatus();\n const provider = useOpenFeatureProvider();\n\n if (defaultedOptions.suspendUntilReady && status === ProviderStatus.NOT_READY) {\n suspendUntilInitialized(provider, client);\n }\n\n return status === ProviderStatus.READY;\n}\n", "import type { InMemoryFlagConfiguration, JsonValue, Provider } from '@openfeature/web-sdk';\nimport { TypedInMemoryProvider, NOOP_PROVIDER, OpenFeature } from '@openfeature/web-sdk';\nimport React from 'react';\nimport type { NormalizedOptions } from '../options';\nimport { OpenFeatureProvider } from './provider';\n\ntype FlagValueMap = { [flagKey: string]: JsonValue };\ntype TestProviderProps = Omit<React.ComponentProps<typeof OpenFeatureProvider>, 'client'> &\n (\n | {\n provider?: never;\n /**\n * Optional map of flagKeys to flagValues for this OpenFeatureTestProvider context.\n * If not supplied, all flag evaluations will default.\n */\n flagValueMap?: FlagValueMap;\n /**\n * Optional delay for the underlying test provider's readiness and reconciliation.\n * Defaults to 0.\n */\n delayMs?: number;\n }\n | {\n /**\n * An optional partial provider to pass for full control over the flag resolution for this OpenFeatureTestProvider context.\n * Any un-implemented methods or properties will no-op.\n */\n provider?: Partial<Provider>;\n flagValueMap?: never;\n delayMs?: never;\n }\n );\n\nconst TEST_VARIANT = 'test-variant';\nconst TEST_PROVIDER = 'test-provider';\n\n// internal provider which is basically the in-memory provider with a simpler config and some optional fake delays\nclass TestProvider extends TypedInMemoryProvider {\n // initially make this undefined, we still set it if a delay is specified\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore - For maximum compatibility with previous versions, we ignore a possible TS error here,\n // since \"initialize\" was previously defined in superclass.\n // We can safely remove this ts-ignore in a few versions\n initialize: Provider['initialize'] = undefined;\n\n // \"place-holder\" init function which we only assign if want a delay\n private delayedInitialize = async () => {\n await new Promise<void>((resolve) => setTimeout(resolve, this.delay));\n };\n\n constructor(\n flagValueMap: FlagValueMap,\n private delay = 0,\n ) {\n // convert the simple flagValueMap into an in-memory config\n const flagConfig = Object.entries(flagValueMap).reduce(\n (acc: InMemoryFlagConfiguration, flag): InMemoryFlagConfiguration => {\n return {\n ...acc,\n [flag[0]]: {\n variants: {\n [TEST_VARIANT]: flag[1],\n },\n defaultVariant: TEST_VARIANT,\n disabled: false,\n },\n };\n },\n {},\n );\n super(flagConfig);\n // only define and init if there's a non-zero delay specified\n this.initialize = this.delay ? this.delayedInitialize.bind(this) : undefined;\n }\n\n async onContextChange() {\n return new Promise<void>((resolve) => setTimeout(resolve, this.delay));\n }\n}\n\n/**\n * A React Context provider based on the {@link TypedInMemoryProvider}, specifically built for testing.\n * Use this for testing components that use flag evaluation hooks.\n * @param {TestProviderProps} testProviderOptions options for the OpenFeatureTestProvider\n * @returns {OpenFeatureProvider} OpenFeatureTestProvider\n */\nexport function OpenFeatureTestProvider(testProviderOptions: TestProviderProps) {\n const { flagValueMap, provider } = testProviderOptions;\n const effectiveProvider = (\n flagValueMap ? new TestProvider(flagValueMap, testProviderOptions.delayMs) : mixInNoop(provider) || NOOP_PROVIDER\n ) as Provider;\n testProviderOptions.domain\n ? OpenFeature.setProvider(testProviderOptions.domain, effectiveProvider)\n : OpenFeature.setProvider(effectiveProvider);\n\n return (\n <OpenFeatureProvider {...(testProviderOptions as NormalizedOptions)} domain={testProviderOptions.domain}>\n {testProviderOptions.children}\n </OpenFeatureProvider>\n );\n}\n\n// mix in the no-op provider when the partial is passed\nfunction mixInNoop(provider: Partial<Provider> = {}) {\n // fill in any missing methods with no-ops\n for (const prop of Object.getOwnPropertyNames(Object.getPrototypeOf(NOOP_PROVIDER)).filter(\n (prop) => prop !== 'constructor',\n )) {\n const patchedProvider = provider as { [key: string]: keyof Provider };\n if (!Object.getPrototypeOf(patchedProvider)[prop] && !patchedProvider[prop]) {\n patchedProvider[prop] = Object.getPrototypeOf(NOOP_PROVIDER)[prop];\n }\n }\n // fill in the metadata if missing\n if (!provider.metadata || !provider.metadata.name) {\n (provider.metadata as unknown) = { name: TEST_PROVIDER };\n }\n return provider;\n}\n", "import { useCallback, useContext, useEffect, useState } from 'react';\nimport type { EvaluationContext } from '@openfeature/web-sdk';\nimport { OpenFeature } from '@openfeature/web-sdk';\nimport { Context } from '../internal';\n\nexport type ContextMutationOptions = {\n /**\n * Mutate the default context instead of the domain scoped context applied at the `<OpenFeatureProvider/>`.\n * By default, will use the domain set on `<OpenFeatureProvider/>` (or the domain associated with the client set on `<OpenFeatureProvider/>`).\n * See the {@link https://openfeature.dev/docs/reference/technologies/client/web/#manage-evaluation-context-for-domains|documentation} for more information.\n * @default false\n */\n defaultContext?: boolean;\n};\n\nexport type ContextMutation = {\n /**\n * Context-aware function to set the desired context (see: {@link ContextMutationOptions} for details).\n * There's generally no need to await the result of this function; flag evaluation hooks will re-render when the context is updated.\n * This promise never rejects.\n * @param updatedContext New context object or method to generate it from the current context\n * @returns Promise for awaiting the context update\n */\n setContext: (\n updatedContext: EvaluationContext | ((currentContext: EvaluationContext) => EvaluationContext),\n ) => Promise<void>;\n};\n\n/**\n * Get context-aware tracking function(s) for mutating the evaluation context associated with this domain, or the default context if `defaultContext: true`.\n * See the {@link https://openfeature.dev/docs/reference/technologies/client/web/#targeting-and-context|documentation} for more information.\n * @param {ContextMutationOptions} options options for the generated function\n * @returns {ContextMutation} context-aware function(s) to mutate evaluation context\n */\nexport function useContextMutator(options: ContextMutationOptions = { defaultContext: false }): ContextMutation {\n const { client } = useContext(Context) || {};\n const domain = client?.metadata.domain;\n\n // TODO: Replace this warning with a thrown error in a future major release,\n // to match the behavior of `useOpenFeatureProvider` + `useOpenFeatureClient`,\n // when `defaultContext` isn't explicitly set to true.\n const [warned, setWarned] = useState(false);\n useEffect(() => {\n if (options.defaultContext || domain) {\n if (warned) {\n setWarned(false);\n }\n return;\n }\n\n if (!warned) {\n console.warn(\n '[useContextMutator] No domain available from OpenFeature context; are you using <OpenFeatureProvider/>? setContext will mutate the default context, as if `defaultContext: true` were set. This may result in a thrown error in the future.',\n );\n setWarned(true);\n }\n }, [warned]);\n\n const setContext = useCallback(\n async (\n updatedContext: EvaluationContext | ((currentContext: EvaluationContext) => EvaluationContext),\n ): Promise<void> => {\n const previousContext = OpenFeature.getContext(options?.defaultContext ? undefined : domain);\n const resolvedContext = typeof updatedContext === 'function' ? updatedContext(previousContext) : updatedContext;\n\n if (previousContext !== resolvedContext) {\n if (!domain || options?.defaultContext) {\n await OpenFeature.setContext(resolvedContext);\n } else {\n await OpenFeature.setContext(domain, resolvedContext);\n }\n }\n },\n [domain, options?.defaultContext],\n );\n\n return {\n setContext,\n };\n}\n", "import type { Tracking, TrackingEventDetails } from '@openfeature/web-sdk';\nimport { useCallback } from 'react';\nimport { useOpenFeatureClient } from '../provider';\n\nexport type Track = {\n /**\n * Context-aware tracking function for the parent `<OpenFeatureProvider/>`.\n * Track a user action or application state, usually representing a business objective or outcome.\n * @param trackingEventName an identifier for the event\n * @param trackingEventDetails the details of the tracking event\n */\n track: Tracking['track'];\n};\n\n/**\n * Get a context-aware tracking function.\n * @returns {Track} context-aware tracking\n */\nexport function useTrack(): Track {\n const client = useOpenFeatureClient();\n\n const track = useCallback((trackingEventName: string, trackingEventDetails?: TrackingEventDetails) => {\n client.track(trackingEventName, trackingEventDetails);\n }, []);\n\n return {\n track,\n };\n}\n", "export * from './declarative';\nexport * from './evaluation';\nexport * from './query';\nexport * from './provider';\nexport * from './context';\nexport * from './tracking';\nexport * from './options';\n// re-export the web-sdk so consumers can access that API from the react-sdk\nexport * from '@openfeature/web-sdk';\n"],
5
+ "mappings": "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",
6
6
  "names": ["React", "ProviderEvents", "useEffect", "useState", "React", "React", "React", "ProviderEvents", "React", "React", "useState", "useEffect", "ProviderEvents", "fallbackNode", "React", "OpenFeature", "React", "OpenFeature", "ProviderStatus", "ProviderStatus", "NOOP_PROVIDER", "OpenFeature", "React", "NOOP_PROVIDER", "OpenFeature", "React", "prop", "useCallback", "useEffect", "useState", "OpenFeature", "useState", "useEffect", "useCallback", "OpenFeature", "useCallback", "useCallback"]
7
7
  }
package/dist/types.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import React__default from 'react';
3
3
  import { FlagValue, EvaluationDetails, FlagMetadata, StandardResolutionReasons, ErrorCode } from '@openfeature/core';
4
- import { FlagEvaluationOptions, FlagValue as FlagValue$1, JsonValue, EvaluationDetails as EvaluationDetails$1, Client, ProviderStatus, Provider, EvaluationContext, Tracking } from '@openfeature/web-sdk';
4
+ import { FlagEvaluationOptions, FlagValue as FlagValue$1, ConstrainedFlagKey, EvaluationDetails as EvaluationDetails$1, JsonValue, BooleanFlagKey, StringFlagKey, NumberFlagKey, ObjectFlagKey, Client, ProviderStatus, Provider, EvaluationContext, Tracking } from '@openfeature/web-sdk';
5
5
  export * from '@openfeature/web-sdk';
6
6
 
7
7
  interface FlagQuery<T extends FlagValue = FlagValue> {
@@ -102,11 +102,11 @@ type NormalizedOptions = Omit<ReactFlagEvaluationOptions, 'suspend'>;
102
102
  * Props for the FeatureFlag component that conditionally renders content based on feature flag state.
103
103
  * @interface FeatureFlagProps
104
104
  */
105
- interface FeatureFlagProps<T extends FlagValue = FlagValue> {
105
+ interface FeatureFlagProps<T extends FlagValue$1 = FlagValue$1> {
106
106
  /**
107
107
  * The key of the feature flag to evaluate.
108
108
  */
109
- flagKey: string;
109
+ flagKey: ConstrainedFlagKey<T>;
110
110
  /**
111
111
  * Optional predicate function for custom matching logic.
112
112
  * If provided, this function will be used instead of the default equality check.
@@ -114,7 +114,7 @@ interface FeatureFlagProps<T extends FlagValue = FlagValue> {
114
114
  * @param details The evaluation details
115
115
  * @returns true if the condition is met, false otherwise
116
116
  */
117
- predicate?: (matchValue: T | undefined, details: EvaluationDetails<T>) => boolean;
117
+ predicate?: (matchValue: T | undefined, details: EvaluationDetails$1<T>) => boolean;
118
118
  /**
119
119
  * Content to render when the feature flag condition is met.
120
120
  * Can be a React node or a function that receives flag query details and returns a React node.
@@ -124,7 +124,7 @@ interface FeatureFlagProps<T extends FlagValue = FlagValue> {
124
124
  * Optional content to render when the feature flag condition is not met.
125
125
  * Can be a React node or a function that receives evaluation details and returns a React node.
126
126
  */
127
- fallback?: React__default.ReactNode | ((details: EvaluationDetails<T>) => React__default.ReactNode);
127
+ fallback?: React__default.ReactNode | ((details: EvaluationDetails$1<T>) => React__default.ReactNode);
128
128
  /**
129
129
  * Flag evaluation options that will be passed to useFlag hook.
130
130
  */
@@ -135,7 +135,7 @@ interface FeatureFlagProps<T extends FlagValue = FlagValue> {
135
135
  * For boolean flags, `match` is optional (defaults to checking truthiness).
136
136
  * For non-boolean flags (string, number, object), `match` is required to determine when to render.
137
137
  */
138
- type FeatureFlagMatchConfig<T extends FlagValue> = {
138
+ type FeatureFlagMatchConfig<T extends FlagValue$1> = {
139
139
  /**
140
140
  * Default value to use when the feature flag is not found.
141
141
  */
@@ -153,124 +153,124 @@ type FeatureFlagMatchConfig<T extends FlagValue> = {
153
153
  */
154
154
  matchValue: T;
155
155
  });
156
- type FeatureFlagComponentProps<T extends FlagValue> = FeatureFlagProps<T> & FeatureFlagMatchConfig<T>;
156
+ type FeatureFlagComponentProps<T extends FlagValue$1> = FeatureFlagProps<T> & FeatureFlagMatchConfig<T>;
157
157
  /**
158
158
  * @experimental This API is experimental, and is subject to change.
159
159
  * FeatureFlag component that conditionally renders its children based on the evaluation of a feature flag.
160
160
  * @param {FeatureFlagComponentProps} props The properties for the FeatureFlag component.
161
161
  * @returns {React.ReactElement | null} The rendered component or null if the feature is not enabled.
162
162
  */
163
- declare function FeatureFlag<T extends FlagValue = FlagValue>({ flagKey, matchValue, predicate, defaultValue, children, evaluationOptions, fallback, }: FeatureFlagComponentProps<T>): React__default.ReactElement | null;
163
+ declare function FeatureFlag<T extends FlagValue$1 = FlagValue$1>({ flagKey, matchValue, predicate, defaultValue, children, evaluationOptions, fallback, }: FeatureFlagComponentProps<T>): React__default.ReactElement | null;
164
164
 
165
165
  /**
166
166
  * Evaluates a feature flag generically, returning an react-flavored queryable object.
167
167
  * The resolver method to use is based on the type of the defaultValue.
168
168
  * For type-specific hooks, use {@link useBooleanFlagValue}, {@link useBooleanFlagDetails} and equivalents.
169
169
  * By default, components will re-render when the flag value changes.
170
- * @param {string} flagKey the flag identifier
170
+ * @param {ConstrainedFlagKey<T>} flagKey the flag identifier
171
171
  * @template {FlagValue} T A optional generic argument constraining the default.
172
172
  * @param {T} defaultValue the default value; used to determine what resolved type should be used.
173
173
  * @param {ReactFlagEvaluationOptions} options for this evaluation
174
174
  * @returns { FlagQuery } a queryable object containing useful information about the flag.
175
175
  */
176
- declare function useFlag<T extends FlagValue$1 = FlagValue$1>(flagKey: string, defaultValue: T, options?: ReactFlagEvaluationOptions): FlagQuery<T extends boolean ? boolean : T extends number ? number : T extends string ? string : T extends JsonValue ? T : JsonValue>;
176
+ declare function useFlag<T extends FlagValue$1 = FlagValue$1>(flagKey: ConstrainedFlagKey<T>, defaultValue: T, options?: ReactFlagEvaluationOptions): FlagQuery<T extends boolean ? boolean : T extends number ? number : T extends string ? string : T extends JsonValue ? T : JsonValue>;
177
177
  type UseFlagReturn<T extends FlagValue$1> = ReturnType<typeof useFlag<T>>;
178
178
  /**
179
179
  * Equivalent to {@link useFlag} with `options: { suspend: true }`
180
180
  * @experimental Suspense is an experimental feature subject to change in future versions.
181
- * @param {string} flagKey the flag identifier
181
+ * @param {ConstrainedFlagKey<T>} flagKey the flag identifier
182
182
  * @template {FlagValue} T A optional generic argument constraining the default.
183
183
  * @param {T} defaultValue the default value; used to determine what resolved type should be used.
184
184
  * @param {ReactFlagEvaluationNoSuspenseOptions} options for this evaluation
185
185
  * @returns { UseFlagReturn<T> } a queryable object containing useful information about the flag.
186
186
  */
187
- declare function useSuspenseFlag<T extends FlagValue$1 = FlagValue$1>(flagKey: string, defaultValue: T, options?: ReactFlagEvaluationNoSuspenseOptions): UseFlagReturn<T>;
187
+ declare function useSuspenseFlag<T extends FlagValue$1 = FlagValue$1>(flagKey: ConstrainedFlagKey<T>, defaultValue: T, options?: ReactFlagEvaluationNoSuspenseOptions): UseFlagReturn<T>;
188
188
  /**
189
189
  * Evaluates a feature flag, returning a boolean.
190
190
  * By default, components will re-render when the flag value changes.
191
191
  * For a generic hook returning a queryable interface, see {@link useFlag}.
192
- * @param {string} flagKey the flag identifier
192
+ * @param {BooleanFlagKey} flagKey the flag identifier
193
193
  * @param {boolean} defaultValue the default value
194
194
  * @param {ReactFlagEvaluationOptions} options options for this evaluation
195
195
  * @returns { boolean} a EvaluationDetails object for this evaluation
196
196
  */
197
- declare function useBooleanFlagValue(flagKey: string, defaultValue: boolean, options?: ReactFlagEvaluationOptions): boolean;
197
+ declare function useBooleanFlagValue(flagKey: BooleanFlagKey, defaultValue: boolean, options?: ReactFlagEvaluationOptions): boolean;
198
198
  /**
199
199
  * Evaluates a feature flag, returning evaluation details.
200
200
  * By default, components will re-render when the flag value changes.
201
201
  * For a generic hook returning a queryable interface, see {@link useFlag}.
202
- * @param {string} flagKey the flag identifier
202
+ * @param {BooleanFlagKey} flagKey the flag identifier
203
203
  * @param {boolean} defaultValue the default value
204
204
  * @param {ReactFlagEvaluationOptions} options options for this evaluation
205
205
  * @returns { EvaluationDetails<boolean>} a EvaluationDetails object for this evaluation
206
206
  */
207
- declare function useBooleanFlagDetails(flagKey: string, defaultValue: boolean, options?: ReactFlagEvaluationOptions): EvaluationDetails$1<boolean>;
207
+ declare function useBooleanFlagDetails(flagKey: BooleanFlagKey, defaultValue: boolean, options?: ReactFlagEvaluationOptions): EvaluationDetails$1<boolean>;
208
208
  /**
209
209
  * Evaluates a feature flag, returning a string.
210
210
  * By default, components will re-render when the flag value changes.
211
211
  * For a generic hook returning a queryable interface, see {@link useFlag}.
212
- * @param {string} flagKey the flag identifier
212
+ * @param {StringFlagKey} flagKey the flag identifier
213
213
  * @template {string} [T=string] A optional generic argument constraining the string
214
214
  * @param {T} defaultValue the default value
215
215
  * @param {ReactFlagEvaluationOptions} options options for this evaluation
216
216
  * @returns { boolean} a EvaluationDetails object for this evaluation
217
217
  */
218
- declare function useStringFlagValue<T extends string = string>(flagKey: string, defaultValue: T, options?: ReactFlagEvaluationOptions): string;
218
+ declare function useStringFlagValue<T extends string = string>(flagKey: StringFlagKey, defaultValue: T, options?: ReactFlagEvaluationOptions): string;
219
219
  /**
220
220
  * Evaluates a feature flag, returning evaluation details.
221
221
  * By default, components will re-render when the flag value changes.
222
222
  * For a generic hook returning a queryable interface, see {@link useFlag}.
223
- * @param {string} flagKey the flag identifier
223
+ * @param {StringFlagKey} flagKey the flag identifier
224
224
  * @template {string} [T=string] A optional generic argument constraining the string
225
225
  * @param {T} defaultValue the default value
226
226
  * @param {ReactFlagEvaluationOptions} options options for this evaluation
227
227
  * @returns { EvaluationDetails<string>} a EvaluationDetails object for this evaluation
228
228
  */
229
- declare function useStringFlagDetails<T extends string = string>(flagKey: string, defaultValue: T, options?: ReactFlagEvaluationOptions): EvaluationDetails$1<string>;
229
+ declare function useStringFlagDetails<T extends string = string>(flagKey: StringFlagKey, defaultValue: T, options?: ReactFlagEvaluationOptions): EvaluationDetails$1<string>;
230
230
  /**
231
231
  * Evaluates a feature flag, returning a number.
232
232
  * By default, components will re-render when the flag value changes.
233
233
  * For a generic hook returning a queryable interface, see {@link useFlag}.
234
- * @param {string} flagKey the flag identifier
234
+ * @param {NumberFlagKey} flagKey the flag identifier
235
235
  * @template {number} [T=number] A optional generic argument constraining the number
236
236
  * @param {T} defaultValue the default value
237
237
  * @param {ReactFlagEvaluationOptions} options options for this evaluation
238
238
  * @returns { boolean} a EvaluationDetails object for this evaluation
239
239
  */
240
- declare function useNumberFlagValue<T extends number = number>(flagKey: string, defaultValue: T, options?: ReactFlagEvaluationOptions): number;
240
+ declare function useNumberFlagValue<T extends number = number>(flagKey: NumberFlagKey, defaultValue: T, options?: ReactFlagEvaluationOptions): number;
241
241
  /**
242
242
  * Evaluates a feature flag, returning evaluation details.
243
243
  * By default, components will re-render when the flag value changes.
244
244
  * For a generic hook returning a queryable interface, see {@link useFlag}.
245
- * @param {string} flagKey the flag identifier
245
+ * @param {NumberFlagKey} flagKey the flag identifier
246
246
  * @template {number} [T=number] A optional generic argument constraining the number
247
247
  * @param {T} defaultValue the default value
248
248
  * @param {ReactFlagEvaluationOptions} options options for this evaluation
249
249
  * @returns { EvaluationDetails<number>} a EvaluationDetails object for this evaluation
250
250
  */
251
- declare function useNumberFlagDetails<T extends number = number>(flagKey: string, defaultValue: T, options?: ReactFlagEvaluationOptions): EvaluationDetails$1<number>;
251
+ declare function useNumberFlagDetails<T extends number = number>(flagKey: NumberFlagKey, defaultValue: T, options?: ReactFlagEvaluationOptions): EvaluationDetails$1<number>;
252
252
  /**
253
253
  * Evaluates a feature flag, returning an object.
254
254
  * By default, components will re-render when the flag value changes.
255
255
  * For a generic hook returning a queryable interface, see {@link useFlag}.
256
- * @param {string} flagKey the flag identifier
256
+ * @param {ObjectFlagKey} flagKey the flag identifier
257
257
  * @template {JsonValue} [T=JsonValue] A optional generic argument describing the structure
258
258
  * @param {T} defaultValue the default value
259
259
  * @param {ReactFlagEvaluationOptions} options options for this evaluation
260
260
  * @returns { boolean} a EvaluationDetails object for this evaluation
261
261
  */
262
- declare function useObjectFlagValue<T extends JsonValue = JsonValue>(flagKey: string, defaultValue: T, options?: ReactFlagEvaluationOptions): T;
262
+ declare function useObjectFlagValue<T extends JsonValue = JsonValue>(flagKey: ObjectFlagKey, defaultValue: T, options?: ReactFlagEvaluationOptions): T;
263
263
  /**
264
264
  * Evaluates a feature flag, returning evaluation details.
265
265
  * By default, components will re-render when the flag value changes.
266
266
  * For a generic hook returning a queryable interface, see {@link useFlag}.
267
- * @param {string} flagKey the flag identifier
267
+ * @param {ObjectFlagKey} flagKey the flag identifier
268
268
  * @param {T} defaultValue the default value
269
269
  * @template {JsonValue} [T=JsonValue] A optional generic argument describing the structure
270
270
  * @param {ReactFlagEvaluationOptions} options options for this evaluation
271
271
  * @returns { EvaluationDetails<T>} a EvaluationDetails object for this evaluation
272
272
  */
273
- declare function useObjectFlagDetails<T extends JsonValue = JsonValue>(flagKey: string, defaultValue: T, options?: ReactFlagEvaluationOptions): EvaluationDetails$1<T>;
273
+ declare function useObjectFlagDetails<T extends JsonValue = JsonValue>(flagKey: ObjectFlagKey, defaultValue: T, options?: ReactFlagEvaluationOptions): EvaluationDetails$1<T>;
274
274
 
275
275
  type ClientOrDomain = {
276
276
  /**
@@ -348,7 +348,7 @@ type TestProviderProps = Omit<React__default.ComponentProps<typeof OpenFeaturePr
348
348
  delayMs?: never;
349
349
  });
350
350
  /**
351
- * A React Context provider based on the {@link InMemoryProvider}, specifically built for testing.
351
+ * A React Context provider based on the {@link TypedInMemoryProvider}, specifically built for testing.
352
352
  * Use this for testing components that use flag evaluation hooks.
353
353
  * @param {TestProviderProps} testProviderOptions options for the OpenFeatureTestProvider
354
354
  * @returns {OpenFeatureProvider} OpenFeatureTestProvider
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openfeature/react-sdk",
3
- "version": "1.2.1",
3
+ "version": "1.4.0",
4
4
  "description": "OpenFeature React SDK",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "files": [
@@ -47,11 +47,12 @@
47
47
  },
48
48
  "homepage": "https://github.com/open-feature/js-sdk#readme",
49
49
  "peerDependencies": {
50
- "@openfeature/web-sdk": "^1.5.0",
50
+ "@openfeature/web-sdk": "^1.9.0",
51
51
  "react": ">=16.8.0"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@openfeature/core": "*",
55
55
  "@openfeature/web-sdk": "*"
56
- }
56
+ },
57
+ "sideEffects": false
57
58
  }