feat: FlagManager.applyChanges for FDv2 full/partial/none semantics#1208
Merged
Conversation
…xtensions Add InitializerEntry/SynchronizerEntry types for type-safe mode definitions, refine protocolHandler validation to use isNullish for version/target fields, add connectionModes config option, split validator arrays for initializers vs synchronizers, and extend DataManager with optional streaming/flush methods.
Add applyChanges method to FlagManager and FlagPersistence that handles full replacement, partial upsert, and no-change persistence in a single call, designed for the FDv2 data path.
kinyoklion
commented
Mar 19, 2026
This was referenced Mar 19, 2026
joker23
reviewed
Mar 20, 2026
kinyoklion
added a commit
that referenced
this pull request
Mar 20, 2026
## Summary
Converts: `{polling: {initializers: ['cache', 'polling'], synchronizers:
['streaming']}}` into real factories.
- Add `SourceFactoryProvider` interface and
`createDefaultSourceFactoryProvider` implementation
- Converts declarative `InitializerEntry`/`SynchronizerEntry` config
into concrete factories and synchronizer slots
- Supports per-entry endpoint overrides (custom polling/streaming URIs)
and interval overrides
- Handles `cache`, `polling`, and `streaming` entry types
Stacked on #1207. Independent of #1208 (FlagManager.applyChanges).
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Medium Risk**
> Introduces a new factory layer that determines how
polling/streaming/cache sources are instantiated (including
endpoint/interval overrides), which can affect connection behavior if
integrated incorrectly. Changes are well-covered by unit tests and are
otherwise additive.
>
> **Overview**
> Adds a new `SourceFactoryProvider` abstraction (with
`createDefaultSourceFactoryProvider`) that converts declarative
`InitializerEntry`/`SynchronizerEntry` configs into concrete FDv2
initializer factories and synchronizer slots, supporting `cache`,
`polling`, and `streaming` entries.
>
> Implements per-entry overrides for endpoints and timing (poll interval
and streaming reconnect delay), including ensuring the streaming ping
handler always uses the latest selector and any endpoint-overridden
polling requestor.
>
> Exports the new provider/types from `sdk-client` public entrypoint and
updates CI package-size thresholds for `js-sdk-common` and
`js-client-sdk-common` to accommodate the added code/tests.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
de39213. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!-- devin-review-badge-begin -->
---
<a href="https://app.devin.ai/review/launchdarkly/js-core/pull/1209"
target="_blank">
<picture>
<source media="(prefers-color-scheme: dark)"
srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1">
<img
src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1"
alt="Open with Devin">
</picture>
</a>
<!-- devin-review-badge-end -->
… checks Push applyChanges down through the flag manager layers so the FDv2 path no longer routes through FDv1's upsert (which has version checks and inactive-context guards). FlagStore.applyPartial inserts without version comparison, and FlagUpdater.applyChanges sets the active context directly and emits change events.
…er-apply-changes # Conflicts: # packages/shared/sdk-client/src/datasource/fdv2/FDv2DataSource.ts
Contributor
|
@launchdarkly/js-sdk-common size report |
Contributor
|
@launchdarkly/browser size report |
Contributor
|
@launchdarkly/js-client-sdk size report |
Contributor
|
@launchdarkly/js-client-sdk-common size report |
Account for new FDv2 applyChanges code in FlagUpdater/FlagStore that flows into the browser SDK bundle.
Replace FlagStore.applyPartial with FlagStore.applyChanges that handles full/partial/none, delegating to init for full. FlagUpdater.applyChanges now delegates storage to FlagStore.applyChanges and only handles change event computation.
joker23
approved these changes
Mar 20, 2026
Merged
joker23
pushed a commit
that referenced
this pull request
Mar 23, 2026
🤖 I have created a release *beep* *boop* --- <details><summary>akamai-edgeworker-sdk-common: 2.0.17</summary> ## [2.0.17](akamai-edgeworker-sdk-common-v2.0.16...akamai-edgeworker-sdk-common-v2.0.17) (2026-03-23) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-server-sdk-common bumped from ^2.18.2 to ^2.18.3 </details> <details><summary>akamai-server-base-sdk: 3.0.18</summary> ## [3.0.18](akamai-server-base-sdk-v3.0.17...akamai-server-base-sdk-v3.0.18) (2026-03-23) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/akamai-edgeworker-sdk-common bumped from ^2.0.16 to ^2.0.17 * @launchdarkly/js-server-sdk-common bumped from ^2.18.2 to ^2.18.3 </details> <details><summary>akamai-server-edgekv-sdk: 1.4.20</summary> ## [1.4.20](akamai-server-edgekv-sdk-v1.4.19...akamai-server-edgekv-sdk-v1.4.20) (2026-03-23) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/akamai-edgeworker-sdk-common bumped from ^2.0.16 to ^2.0.17 * @launchdarkly/js-server-sdk-common bumped from ^2.18.2 to ^2.18.3 </details> <details><summary>browser: 0.1.13</summary> ## [0.1.13](browser-v0.1.12...browser-v0.1.13) (2026-03-23) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-client-sdk bumped from 4.4.0 to 4.4.1 </details> <details><summary>browser-telemetry: 1.0.29</summary> ## [1.0.29](browser-telemetry-v1.0.28...browser-telemetry-v1.0.29) (2026-03-23) ### Dependencies * The following workspace dependencies were updated * devDependencies * @launchdarkly/js-client-sdk bumped from 4.4.0 to 4.4.1 </details> <details><summary>cloudflare-server-sdk: 2.7.17</summary> ## [2.7.17](cloudflare-server-sdk-v2.7.16...cloudflare-server-sdk-v2.7.17) (2026-03-23) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-server-sdk-common-edge bumped from 2.6.15 to 2.6.16 </details> <details><summary>fastly-server-sdk: 0.2.9</summary> ## [0.2.9](fastly-server-sdk-v0.2.8...fastly-server-sdk-v0.2.9) (2026-03-23) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-server-sdk-common bumped from 2.18.2 to 2.18.3 </details> <details><summary>jest: 1.0.8</summary> ## [1.0.8](jest-v1.0.7...jest-v1.0.8) (2026-03-23) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/react-native-client-sdk bumped from ~10.15.0 to ~10.15.1 </details> <details><summary>js-client-sdk: 4.4.1</summary> ## [4.4.1](js-client-sdk-v4.4.0...js-client-sdk-v4.4.1) (2026-03-23) ### Bug Fixes * Report data source state as valid after bootstrap ([#1203](#1203)) ([b00889f](b00889f)) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-client-sdk-common bumped from 1.22.0 to 1.23.0 </details> <details><summary>js-client-sdk-common: 1.23.0</summary> ## [1.23.0](js-client-sdk-common-v1.22.0...js-client-sdk-common-v1.23.0) (2026-03-23) ### Features * FDv2 types, refined validators, and DataManager interface ([#1207](#1207)) ([d7ccfc1](d7ccfc1)) * FlagManager.applyChanges for FDv2 full/partial/none semantics ([#1208](#1208)) ([d9a1bd7](d9a1bd7)) * SourceFactoryProvider for declarative data source creation ([#1209](#1209)) ([e254f77](e254f77)) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-sdk-common bumped from 2.23.0 to 2.24.0 </details> <details><summary>js-sdk-common: 2.24.0</summary> ## [2.24.0](js-sdk-common-v2.23.0...js-sdk-common-v2.24.0) (2026-03-23) ### Features * FDv2 types, refined validators, and DataManager interface ([#1207](#1207)) ([d7ccfc1](d7ccfc1)) </details> <details><summary>js-server-sdk-common: 2.18.3</summary> ## [2.18.3](js-server-sdk-common-v2.18.2...js-server-sdk-common-v2.18.3) (2026-03-23) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-sdk-common bumped from 2.23.0 to 2.24.0 </details> <details><summary>js-server-sdk-common-edge: 2.6.16</summary> ## [2.6.16](js-server-sdk-common-edge-v2.6.15...js-server-sdk-common-edge-v2.6.16) (2026-03-23) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-server-sdk-common bumped from 2.18.2 to 2.18.3 </details> <details><summary>node-server-sdk: 9.10.10</summary> ## [9.10.10](node-server-sdk-v9.10.9...node-server-sdk-v9.10.10) (2026-03-23) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-server-sdk-common bumped from 2.18.2 to 2.18.3 </details> <details><summary>node-server-sdk-dynamodb: 6.2.22</summary> ## [6.2.22](node-server-sdk-dynamodb-v6.2.21...node-server-sdk-dynamodb-v6.2.22) (2026-03-23) ### Dependencies * The following workspace dependencies were updated * devDependencies * @launchdarkly/node-server-sdk bumped from 9.10.9 to 9.10.10 * peerDependencies * @launchdarkly/node-server-sdk bumped from >=9.4.3 to >=9.10.10 </details> <details><summary>node-server-sdk-otel: 1.3.10</summary> ## [1.3.10](node-server-sdk-otel-v1.3.9...node-server-sdk-otel-v1.3.10) (2026-03-23) ### Dependencies * The following workspace dependencies were updated * devDependencies * @launchdarkly/node-server-sdk bumped from 9.10.9 to 9.10.10 * peerDependencies * @launchdarkly/node-server-sdk bumped from >=9.4.3 to >=9.10.10 </details> <details><summary>node-server-sdk-redis: 4.2.22</summary> ## [4.2.22](node-server-sdk-redis-v4.2.21...node-server-sdk-redis-v4.2.22) (2026-03-23) ### Dependencies * The following workspace dependencies were updated * devDependencies * @launchdarkly/node-server-sdk bumped from 9.10.9 to 9.10.10 * peerDependencies * @launchdarkly/node-server-sdk bumped from >=9.4.3 to >=9.10.10 </details> <details><summary>react-native-client-sdk: 10.15.1</summary> ## [10.15.1](react-native-client-sdk-v10.15.0...react-native-client-sdk-v10.15.1) (2026-03-23) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-client-sdk-common bumped from 1.22.0 to 1.23.0 </details> <details><summary>react-sdk: 0.1.0</summary> ## [0.1.0](react-sdk-v0.0.1...react-sdk-v0.1.0) (2026-03-23) ### Features * pre-release of `@launchdarkly/react-sdk` ([#1201](#1201)) ([69f4790](69f4790)) ### Bug Fixes * **deps:** update dependency next to v16.1.5 [security] ([#1164](#1164)) ([929a385](929a385)) * **deps:** update dependency next to v16.1.7 [security] ([#1196](#1196)) ([1572be1](1572be1)) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-client-sdk bumped from ^4.4.0 to ^4.4.1 * @launchdarkly/js-server-sdk-common bumped from ^2.18.2 to ^2.18.3 </details> <details><summary>server-sdk-ai: 0.16.7</summary> ## [0.16.7](server-sdk-ai-v0.16.6...server-sdk-ai-v0.16.7) (2026-03-23) ### Dependencies * The following workspace dependencies were updated * devDependencies * @launchdarkly/js-server-sdk-common bumped from 2.18.2 to 2.18.3 * peerDependencies * @launchdarkly/js-server-sdk-common bumped from 2.x to 2.18.3 </details> <details><summary>server-sdk-ai-langchain: 0.5.3</summary> ## [0.5.3](server-sdk-ai-langchain-v0.5.2...server-sdk-ai-langchain-v0.5.3) (2026-03-23) ### Dependencies * The following workspace dependencies were updated * devDependencies * @launchdarkly/server-sdk-ai bumped from ^0.16.6 to ^0.16.7 * peerDependencies * @launchdarkly/server-sdk-ai bumped from ^0.15.0 || ^0.16.0 to ^0.16.7 </details> <details><summary>server-sdk-ai-openai: 0.5.3</summary> ## [0.5.3](server-sdk-ai-openai-v0.5.2...server-sdk-ai-openai-v0.5.3) (2026-03-23) ### Dependencies * The following workspace dependencies were updated * devDependencies * @launchdarkly/js-server-sdk-common bumped from 2.18.2 to 2.18.3 * @launchdarkly/server-sdk-ai bumped from ^0.16.6 to ^0.16.7 * peerDependencies * @launchdarkly/server-sdk-ai bumped from ^0.15.0 || ^0.16.0 to ^0.16.7 </details> <details><summary>server-sdk-ai-vercel: 0.5.3</summary> ## [0.5.3](server-sdk-ai-vercel-v0.5.2...server-sdk-ai-vercel-v0.5.3) (2026-03-23) ### Dependencies * The following workspace dependencies were updated * devDependencies * @launchdarkly/server-sdk-ai bumped from ^0.16.6 to ^0.16.7 * peerDependencies * @launchdarkly/server-sdk-ai bumped from ^0.15.0 || ^0.16.0 to ^0.16.7 </details> <details><summary>shopify-oxygen-sdk: 0.1.7</summary> ## [0.1.7](shopify-oxygen-sdk-v0.1.6...shopify-oxygen-sdk-v0.1.7) (2026-03-23) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-server-sdk-common bumped from 2.18.2 to 2.18.3 </details> <details><summary>vercel-server-sdk: 1.3.42</summary> ## [1.3.42](vercel-server-sdk-v1.3.41...vercel-server-sdk-v1.3.42) (2026-03-23) ### Dependencies * The following workspace dependencies were updated * dependencies * @launchdarkly/js-server-sdk-common-edge bumped from 2.6.15 to 2.6.16 </details> --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Primarily metadata-only release changes (version constants, `package.json` deps, and `CHANGELOG.md` updates) with minimal functional code impact. Risk is limited to ensuring version strings and dependency bumps are consistent across packages. > > **Overview** > **Automated release PR** that bumps versions across many packages via release-please and updates `.release-please-manifest.json` accordingly. > > Updates each package’s `package.json` (and a few embedded `sdkVersion`/`version` constants used for user-agent/platform info) plus `CHANGELOG.md` entries, and rolls forward internal dependency pins (notably `@launchdarkly/js-sdk-common` → `2.24.0`, `@launchdarkly/js-client-sdk-common` → `1.23.0`, `@launchdarkly/js-server-sdk-common` → `2.18.3`, and the leaf SDKs that depend on them). > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 46e1356. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
kinyoklion
added a commit
that referenced
this pull request
Mar 25, 2026
#1210) ## Summary - Add `FDv2DataManagerBase` — shared data manager orchestrating FDv2 connection mode switching, state debouncing, and data source lifecycle - Implements `DataManager` interface with foreground/background mode support, forced/automatic streaming control, and flush callbacks - Includes `FlagManager.applyChanges` from #1208 for full/partial/none flag update semantics Stacked on #1209 and #1208. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Adds a new shared FDv2 data manager that controls connection-mode resolution and data source lifecycle, plus updates public `dataSystem` option shapes; mistakes here could affect SDK initialization, reconnection behavior, and flag freshness across platforms. > > **Overview** > Introduces `createFDv2DataManagerBase` (and exported types) as a shared FDv2 orchestration layer that performs mode resolution/debouncing, manages `FDv2DataSource` creation/teardown across identifies and mode changes, tracks selector state, triggers a background flush callback, and optionally appends a blocked FDv1 polling fallback synchronizer. > > Updates the public `dataSystem` configuration model by renaming `initialConnectionMode` to `foregroundConnectionMode` in platform defaults and by making `automaticModeSwitching` a discriminated union (`{type:'automatic'}` vs `{type:'manual', initialConnectionMode}`), with validator support via `validatorOf(..., { is })`; tests are updated and expanded accordingly, including a large new test suite for `FDv2DataManagerBase`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 0786b64. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> <!-- devin-review-badge-begin --> --- <a href="https://app.devin.ai/review/launchdarkly/js-core/pull/1210" target="_blank"> <picture> <source media="(prefers-color-scheme: dark)" srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1"> <img src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1" alt="Open with Devin"> </picture> </a> <!-- devin-review-badge-end -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Review 1207 first.
Summary
applyChanges(context, updates, type)method toFlagManagerinterface andFlagPersistence'full': replaces all flags (like init)'partial': upserts individual flags'none': persists cache (updating freshness) without changing flagsStacked on #1207.
Note
Medium Risk
Touches core flag update/caching behavior by adding a new update path that bypasses version and active-context checks, which could affect consistency if misused. Changes are contained and covered by new unit tests, plus a CI-only workflow tweak.
Overview
Adds a new
FlagManager.applyChanges(context, updates, type)API (and plumbing throughFlagPersistence,FlagUpdater, andFlagStore) to support FDv2 update semantics:fullreplace,partialmerge/upsert without version/active-context guards, andnoneno-op flag changes while still persisting cache/freshness.Updates change-event emission to match the new modes (
initfor full diffs,patchfor partial key lists) and adds unit tests covering replacement vs merge behavior, freshness persistence onnone, version-check bypass, and change callbacks.Separately relaxes the browser CI package-size gate by raising the limit from
25000to34000.Written by Cursor Bugbot for commit b5e5dc3. This will update automatically on new commits. Configure here.