Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
fc5fe4c
feat: add protocol-v2 multivariate flag evaluation
roncohen Sep 16, 2026
7c28d1d
perf: prepare v2 flag lookups and percentage allocations once
roncohen Sep 16, 2026
1127ba8
refactor: use a simple loop for percentage allocation selection
roncohen Sep 16, 2026
fc5fa6f
refactor: preserve generic variant value types through evaluation
roncohen Sep 16, 2026
f05d37e
feat!: expose a v2-only prepared flag evaluator
roncohen Sep 16, 2026
03d9be5
build: prepare evaluator artifacts when packing the workspace
roncohen Sep 16, 2026
8d8bd97
docs: remove SDK rollout note from evaluator changeset
roncohen Sep 16, 2026
912f4fc
fix: distinguish v2 prerelease package identity from v1
roncohen Sep 16, 2026
c597521
build: use the registry v1 alias with distinct v2 package identity
roncohen Sep 16, 2026
1277a59
docs: simplify evaluator readme
roncohen Sep 22, 2026
c9a736d
feat(flag-evaluation): resolve flag and segment collection references
roncohen Oct 29, 2026
ad0d702
feat(flag-evaluation): expose batch and single evaluation methods
roncohen Oct 29, 2026
2448fca
feat(node-sdk): adopt collection values and Boolean-first reads
roncohen Nov 4, 2026
521cf4b
feat: adopt v2 flag values in browser and framework SDKs
roncohen Nov 4, 2026
3cc369b
fix(node-sdk): check registered flag defaults
roncohen Nov 5, 2026
d7ccffe
Merge commit '3cc369ba3b494ae76a0e60e45ece8ca14a740669' into feature/…
roncohen Nov 5, 2026
1729e9e
fix: check registered defaults in browser and framework SDKs
roncohen Nov 5, 2026
595758d
fix(node-sdk): keep internal helpers out of API docs
roncohen Nov 5, 2026
1ed2347
Merge commit '595758d00693eefc677b718c30d8fbb845a2fbad' into feature/…
roncohen Nov 5, 2026
9f3a0ae
fix(browser-sdk): document only public default types
roncohen Nov 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .changeset/browser-framework-collection-values.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
"@reflag/browser-sdk": major
"@reflag/react-sdk": major
"@reflag/vue-sdk": major
---

Adopt protocol-v2 evaluated flags and direct JSON values across Browser, React and Vue.

Bare singular reads return Boolean with an implicit false default. Positional JSON defaults infer widened direct-value types without generated declarations, enforce top-level categories, preserve accepted falsy values, and return independent copies. Null explicitly accepts arbitrary JSON; nested schema validation remains the application's responsibility.

Browser `getFlag()` and `getFlags()` register root checks immediately with genuine selected-key/source/snapshot identity. Delivery stays buffered and identity-aware rate-limited. Diagnostic access and bootstrap serialization do not register checks; defaults, mismatches, overrides and static fallback values do not invent selections. V2 cache/override storage is isolated from v1, and complete evaluated snapshots are validated before acceptance. This requires compatible `/flags/evaluated` and canonical-check ingestion on the server.

React `useFlag()` returns a direct value without suspending. Use the separate `useFlagSuspense()` hook to wait for initialization; missing flags then use the default. Vue `useFlag()` returns a ref to the direct value. Loading, application usage tracking and feedback remain separate hooks/composables. The existing opt-in Suspense controls remain specific to `useOptInFlags`.

Upgrade bootstrap producers/consumers together: only protocol-v2 envelopes from Node SDK v2 are supported; legacy bootstrap wrappers and the Browser `bootstrappedFlags` option are rejected. Move wrapper `.track()`/`.requestFeedback()` calls to ordinary client/framework methods. Undefined clears a value override; null is a JSON override.

Opt-in metadata arrives with ordinary v2 evaluated responses. Bootstrapped clients fetch missing metadata on demand from the same v2 endpoint without replacing server-derived values. Mutations confirm versioned evaluation and membership in one refresh. The unchanged OpenFeature Browser provider and React Native wrapper remain pinned to published v1 SDK dependencies. CLI direct-value generation remains a separate migration.
9 changes: 9 additions & 0 deletions .changeset/browser-framework-registered-defaults.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@reflag/browser-sdk": patch
"@reflag/react-sdk": patch
"@reflag/vue-sdk": patch
---

Accept named-interface defaults in Browser reads and check non-null React/Vue defaults against registered flag value schemas, including React Suspense reads. Preserve Boolean bare reads, explicit-null arbitrary JSON, readonly-default support, default-inferred widening, and runtime JSON validation/copying.

Keep Vue declaration imports pointed at the public Vue types so published refs retain their value types rather than degrading to any.
17 changes: 17 additions & 0 deletions .changeset/multivariate-evaluation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
"@reflag/flag-evaluation": major
---

Introduce a v2-only compiled-variant evaluator:

- `newEvaluator({ flags, segments })` prepares a complete collection and returns `evaluateAll(context)` and `evaluateFlag(context, flagKey)` methods. The batch result contains shared normalized context and per-flag results without repeated context. Single-flag evaluation visits only the requested flag and its dependencies. Unresolved batch entries do not prevent other flags from being evaluated. Remove the v1 value-rule APIs and the one-shot `evaluateFlag` wrapper.
- Preserve flag and segment reference nodes instead of inlining their filters. Flag references explicitly match variant keys; segments remain reusable predicates. Resolve references recursively without dependency-result caching or memoization.
- Preserve diagnostics from unsuccessful referenced rules without suppressing a valid matching selection. Invalid nonmatches remain fail-closed through negation. Propagated diagnostics identify their source flag or segment.
- Reject duplicate keys, missing references, unknown referenced variant keys and cycles at preparation, including mixed flag/segment cycles. Evaluating an unknown flag key throws.
- Preserve arbitrary variant value types through `CompiledFlag<T>` and `EvaluationResult<T>` (default `any`). `resolved: true | false` distinguishes a selected value, including `undefined`, from failure. Successful results require the variant key and matched rule ID.
- Keep membership Sets and prepared percentage bounds private. `ANY_OF` / `NOT_ANY_OF` use cached Set lookups, including under groups and negations; percentage distributions use precomputed bounds and a simple scan.
- Evaluate rules sequentially with explicit fallthrough and source-version/rule/allocation diagnostics.
- Return structured `INVALID_COMPARISON` errors for invalid numeric/date comparisons instead of logging context values. Invalid conditions cannot match through negation.
- Retain the original hash function and threshold rollout filter for boolean cohort compatibility. The inclusive maximum distribution bucket selects the last nonzero allocation.

The runtime exports are `newEvaluator`, `flattenContext`, and `hashInt`. Removed APIs include `evaluateFlagRules`, `newFlagEvaluator`, `evaluateFlag`, the scalar `evaluate` helper, and the legacy `flattenJSON` / `unflattenJSON` helpers.
18 changes: 18 additions & 0 deletions .changeset/node-sdk-collection-values.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
"@reflag/node-sdk": major
"@reflag/openfeature-node-provider": patch
---

Adopt evaluator v2 and the complete `GET /flags` collection protocol in the Node SDK.

- `getFlag(context, key)` and bound `getFlag(key)` are direct Boolean reads with an implicit `false` default. Positional defaults infer the value type, widening literals, without generated declarations. Non-null defaults require the same top-level JSON category; missing/mismatched values use the default without authored-selection metadata. An explicit `null` default accepts arbitrary JSON, including authored null. Nested payload schemas are not validated. There is no flag wrapper, `.isEnabled`, `.config`, or flag `.track()` method. Batch `getFlags()` keeps raw JSON/`undefined` values. Ordinary client `track()` APIs remain separate.
- Singular remote reads share the default contract. Root `getFlagRemote(key, defaultValue, userId?, companyId?, context?)` puts the default second, moving old positional IDs one place right; pass `undefined` for a Boolean read with IDs. Bound `getFlagRemote(key, defaultValue?)` needs no explicit IDs.
- Reads immediately register checks for requested roots. Checks carry the selected variant key as `evalResult`, `sourceVersionId`, and the snapshot `flagStateVersion`. Boolean values send the keys `"true"` / `"false"`. Equal-valued variants and dependency-only version changes retain their distinct identities. Delivery remains buffered and rate-limited.
- Prepare complete flags/segments snapshots before atomically accepting them. Evaluate references recursively without dependency-result caching.
- Persist full graphs and snapshot versions in version-2 fallback snapshots. V1 snapshots are not converted. Built-in storage uses separate versioned keys/files so V1 and V2 clients cannot overwrite one another's snapshots. Local overrides and value-only fallbacks do not fabricate authored variant selections.
- Bootstrap state contains v2 selection results and context/version metadata, without registering browser checks. Existing v1 browser bootstrap consumers require a separate migration; this is not a backwards-compatible bootstrap shape.
- Preserve sync modes, ordinary tracking, bound contexts, and post-evaluation override layering. Update the Express example to consume direct values.

The existing OpenFeature provider and v1 React bootstrap demo remain explicitly pinned to published Node SDK v1 through an npm alias. This prevents automatic workspace dependency upgrades from silently breaking their wrapper/bootstrap contracts; migrating those consumers to multivariate values is separate work.

This release requires the collection-capable evaluator and compatible `/flags` and variant-key check ingestion. It does not migrate legacy remote config into multivariate flag values.
5 changes: 5 additions & 0 deletions .changeset/node-sdk-registered-defaults.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@reflag/node-sdk": patch
---

Check non-null singular-read defaults against the registered flag value type for local, remote, and bound getters. Accept named-interface and readonly defaults, while preserving Boolean bare reads, explicit-null arbitrary JSON, default-inferred widening, and runtime JSON validation/copying.
2 changes: 1 addition & 1 deletion docs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ do
echo "Processing $file..."

# Fix anchor links in globals.md files
if [[ "$file" == *"globals.md" ]]; then
if [ "${file##*/}" = "globals.md" ]; then
sed -r "$SEDCOMMAND" "$file" > "$file.fixed"
rm "$file"
mv "$file.fixed" "$file"
Expand Down
Loading
Loading