Skip to content

Fix opt-in flag typing and bootstrap loading state - #697

Merged
roncohen merged 8 commits into
mainfrom
fix/end-user-opt-in-api-loading
Aug 4, 2026
Merged

roncohen merged 8 commits into
mainfrom
fix/end-user-opt-in-api-loading

Conversation

@roncohen

@roncohen roncohen commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • narrow React and Vue OptInFlag.key to each SDK's generated FlagKey, so values returned by useOptInFlags() pass directly to useSetOptIn()
  • expose browser opt-in loading through getIsLoadingOptInFlags() and the optInFlagsLoadingUpdated event
  • return { flags, isLoading } from the React and Vue useOptInFlags() APIs
  • report opt-in isLoading only while bootstrapped providers fetch opt-in metadata on first use; regular providers continue to use useIsLoading() for their normal initial flags request
  • support provider-level and per-hook Suspense in React while regular flags or required bootstrapped opt-in metadata load
  • keep loading tied to the latest context/bootstrap generation so stale or concurrent refreshes cannot clear newer loading state
  • document manual spinner/empty-state handling, the bootstrapping-specific loading case, and React Suspense behavior

API

React:

const { flags, isLoading } = useOptInFlags();

Vue (both values are computed refs and are automatically unwrapped in templates):

const { flags, isLoading } = useOptInFlags();

With a bootstrapped provider, isLoading is true while fetching opt-in metadata on first use. With a regular provider, opt-in metadata arrives with the normal flags response and useIsLoading() covers that initial request.

Unaugmented SDK consumers still get string flag keys; generated/augmented consumers get their existing FlagKey union without weakening other typed flag APIs.

Tests

Added coverage for:

  • generated React and Vue Flags type augmentation and direct flag.key usage with useSetOptIn()
  • regular-provider loading versus bootstrapped opt-in metadata loading
  • successful and failed bootstrapped metadata refreshes
  • context races, newly applied bootstrap state, stale refreshes, and offline mode
  • React and Vue reactive rerenders
  • React Suspense with regular providers and missing bootstrap metadata
  • React Suspense failure recovery and per-hook opt-out

Commands run:

  • yarn workspace @reflag/browser-sdk test
  • yarn workspace @reflag/react-sdk test
  • yarn workspace @reflag/react-sdk test:types
  • yarn workspace @reflag/vue-sdk test
  • yarn workspace @reflag/vue-sdk test:types
  • yarn lint
  • yarn fmt
  • yarn workspace @reflag/browser-sdk build
  • yarn workspace @reflag/react-sdk build
  • yarn workspace @reflag/react-native-sdk build
  • yarn workspace @reflag/vue-sdk build
  • yarn changeset status

@roncohen
roncohen added this pull request to the merge queue Aug 4, 2026
@roncohen
roncohen removed this pull request from the merge queue due to a manual request Aug 4, 2026
@roncohen
roncohen added this pull request to the merge queue Aug 4, 2026
Merged via the queue into main with commit 879f8d9 Aug 4, 2026
7 checks passed
@roncohen
roncohen deleted the fix/end-user-opt-in-api-loading branch August 4, 2026 19:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant