diff --git a/CHANGELOG.md b/CHANGELOG.md index ee82dd595..9a58beb95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,57 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [6.2.0] - October 22, 2025 + +### New Features + +- **Added support for Contextual Multi-Armed Bandit (CMAB)**: Added support for CMAB experiments(Contextual Bandits rules) with new configuration options and cache control. To get decision from CMAB rules, `decideAsync` and related methods must be used. The sync `decide` method does not support CMABs and will just skip CMAB rules while making decision for a flag. + + #### CMAB Configuration Options + + The following new options have been added to configure the cmab cache: + + ```js + import { createInstance } from '@optimizely/optimizely-sdk' + + const optimizely = createInstance({ + // ... other config options + cmab: { + cacheSize: 1000, // Optional: Set CMAB cache size (default: 1000) + cacheTtl: 30 * 60 * 1000, // Optional: Set CMAB cache TTL in milliseconds (default: 30 * 60 * 1000) + cache: customCache // Optional: Custom cache implementation, instance of CacheWithRemove interface + } + }); + ``` + + #### CMAB-Related OptimizelyDecideOptions + + New decide options are available to control CMAB caching behavior: + + - `OptimizelyDecideOption.IGNORE_CMAB_CACHE`: Bypass CMAB cache for fresh decisions + - `OptimizelyDecideOption.RESET_CMAB_CACHE`: Clear and reset CMAB cache before making decisions + - `OptimizelyDecideOption.INVALIDATE_USER_CMAB_CACHE`: Invalidate CMAB cache for the particular user and experiment + + ```js + + // Example usage with CMAB decide options + const decision = await userContext.decideAsync('feature-flag-key', [ + optimizelySdk.enums.OptimizelyDecideOption.IGNORE_CMAB_CACHE + ]); + ``` + +### Bug Fixes +- Flush events without closing client on page unload which causes event processing to stop working when page is loaded from bfcache ([#1087](https://github.com/optimizely/javascript-sdk/pull/1087)) +- Fixed typo in clientEngine option ([#1095](https://github.com/optimizely/javascript-sdk/pull/1095)) + +## [5.4.0] - Oct 13, 2025 + +### New Features +- Added `customHeaders` option to `datafileOptions` for passing custom HTTP headers in datafile requests ([#1092](https://github.com/optimizely/javascript-sdk/pull/1092)) +### Bug Fixes +- Fix the EventTags type to allow event properties ([#1040](https://github.com/optimizely/javascript-sdk/pull/1040)) +- Fix typo in event.experimentIds field in project config ([#1088](https://github.com/optimizely/javascript-sdk/pull/1088)) + ## [6.1.0] - September 8, 2025 ### New Features diff --git a/lib/export_types.ts b/lib/export_types.ts index ce795dbaa..b620fbb8e 100644 --- a/lib/export_types.ts +++ b/lib/export_types.ts @@ -64,8 +64,8 @@ export type { export type { ErrorHandler } from './error/error_handler'; export type { OpaqueErrorNotifier } from './error/error_notifier_factory'; -export type { Cache } from './utils/cache/cache'; -export type { Store } from './utils/cache/store' +export type { SyncCache, AsyncCache, Cache, SyncCacheWithRemove, AsyncCacheWithRemove, CacheWithRemove } from './utils/cache/cache'; +export type { SyncStore, AsyncStore, Store } from './utils/cache/store' export type { NotificationType, diff --git a/lib/index.browser.tests.js b/lib/index.browser.tests.js index c12ed8ef8..645739cdb 100644 --- a/lib/index.browser.tests.js +++ b/lib/index.browser.tests.js @@ -153,7 +153,7 @@ describe('javascript-sdk (Browser)', function() { }); assert.instanceOf(optlyInstance, Optimizely); - assert.equal(optlyInstance.clientVersion, '6.1.0'); + assert.equal(optlyInstance.clientVersion, '6.2.0'); }); it('should set the JavaScript client engine and version', function() { diff --git a/lib/index.node.tests.js b/lib/index.node.tests.js index 343312174..b52a0f15c 100644 --- a/lib/index.node.tests.js +++ b/lib/index.node.tests.js @@ -88,7 +88,7 @@ describe('optimizelyFactory', function() { }); assert.instanceOf(optlyInstance, Optimizely); - assert.equal(optlyInstance.clientVersion, '6.1.0'); + assert.equal(optlyInstance.clientVersion, '6.2.0'); }); // TODO: user will create and inject an event processor // these tests will be refactored accordingly diff --git a/lib/index.react_native.spec.ts b/lib/index.react_native.spec.ts index 3fa5a6357..d8ed60bea 100644 --- a/lib/index.react_native.spec.ts +++ b/lib/index.react_native.spec.ts @@ -92,7 +92,7 @@ describe('javascript-sdk/react-native', () => { expect(optlyInstance).toBeInstanceOf(Optimizely); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - expect(optlyInstance.clientVersion).toEqual('6.1.0'); + expect(optlyInstance.clientVersion).toEqual('6.2.0'); }); it('should set the React Native JS client engine and javascript SDK version', () => { diff --git a/lib/index.universal.ts b/lib/index.universal.ts index 9aaaa8cd3..11c39c1d1 100644 --- a/lib/index.universal.ts +++ b/lib/index.universal.ts @@ -96,7 +96,8 @@ export type { export type { ErrorHandler } from './error/error_handler'; export type { OpaqueErrorNotifier } from './error/error_notifier_factory'; -export type { Cache } from './utils/cache/cache'; +export type { SyncCache, AsyncCache, Cache, SyncCacheWithRemove, AsyncCacheWithRemove, CacheWithRemove } from './utils/cache/cache'; +export type { SyncStore, AsyncStore, Store } from './utils/cache/store' export type { NotificationType, diff --git a/lib/utils/enums/index.ts b/lib/utils/enums/index.ts index fc95f2ef2..fd76d47ec 100644 --- a/lib/utils/enums/index.ts +++ b/lib/utils/enums/index.ts @@ -41,7 +41,7 @@ export const CONTROL_ATTRIBUTES = { export const JAVASCRIPT_CLIENT_ENGINE = 'javascript-sdk'; export const NODE_CLIENT_ENGINE = 'node-sdk'; export const REACT_NATIVE_JS_CLIENT_ENGINE = 'react-native-js-sdk'; -export const CLIENT_VERSION = '6.1.0'; +export const CLIENT_VERSION = '6.2.0'; /* * Represents the source of a decision for feature management. When a feature diff --git a/package-lock.json b/package-lock.json index 4820c783c..05ce4f677 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@optimizely/optimizely-sdk", - "version": "6.1.0", + "version": "6.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@optimizely/optimizely-sdk", - "version": "6.1.0", + "version": "6.2.0", "license": "Apache-2.0", "dependencies": { "decompress-response": "^7.0.0", diff --git a/package.json b/package.json index 675bb7d4f..f094c577e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@optimizely/optimizely-sdk", - "version": "6.1.0", + "version": "6.2.0", "description": "JavaScript SDK for Optimizely Feature Experimentation, Optimizely Full Stack (legacy), and Optimizely Rollouts", "main": "./dist/index.node.min.js", "browser": "./dist/index.browser.es.min.js",