Skip to content

Conversation

@junaed-optimizely
Copy link
Contributor

@junaed-optimizely junaed-optimizely commented Jan 30, 2026

Summary

This PR introduces a new OptimizelyProvider component as part of the React SDK rewrite. The provider manages client initialization by waiting for client.onReady() and exposes state through React Context.

A new ProviderStateStore class provides lightweight pub/sub state management, tracking isClientReady, userContext and error states. Components can subscribe to state changes without causing unnecessary re-renders of the entire context tree.

The provider handles error cases gracefully, including missing client and initialization failures. Cleanup logic resets the store on unmount to prevent memory leaks.

Test plan

Vitest test framework is added. Jest will be removed after rewrite completion

Issues

  • FSSDK-12249
  • FSSDK-12250

@github-actions
Copy link

github-actions bot commented Jan 30, 2026

Jest Coverage Report

Caution

Test run failed

St.
Category Percentage Covered / Total
🟢 Statements 100% 59/59
🟢 Branches 85.71% 24/28
🟢 Functions 100% 17/17
🟢 Lines 100% 56/56

Test suite run failed

Failed tests: 0/28. Failed suites: 11/13.
  ● Test suite failed to run

    src/client.spec.ts:47:5 - error TS2353: Object literal may only specify known properties, and 'datafile' does not exist in type 'Config'.

    47     datafile: {},
           ~~~~~~~~
    src/client.spec.ts:96:7 - error TS2353: Object literal may only specify known properties, and 'getProjectConfig' does not exist in type 'Client'.

    96       getProjectConfig: jest.fn(() => null),
             ~~~~~~~~~~~~~~~~
    src/client.spec.ts:323:9 - error TS2353: Object literal may only specify known properties, and 'odpOptions' does not exist in type 'Config'.

    323         odpOptions: {
                ~~~~~~~~~~
    src/client.spec.ts:464:9 - error TS2353: Object literal may only specify known properties, and 'sdkKey' does not exist in type 'Config'.

    464         sdkKey: 'sdkKey',
                ~~~~~~
    src/client.spec.ts:472:9 - error TS2353: Object literal may only specify known properties, and 'datafile' does not exist in type 'Config'.

    472         datafile: 'datafile',
                ~~~~~~~~
    src/client.spec.ts:2134:9 - error TS2353: Object literal may only specify known properties, and 'odpOptions' does not exist in type 'Config'.

    2134         odpOptions: {
                 ~~~~~~~~~~
    src/client.spec.ts:2567:14 - error TS18046: 'result' is of type 'unknown'.

    2567       expect(result.success).toBe(true);
                      ~~~~~~
    src/client.spec.ts:2568:14 - error TS18046: 'result' is of type 'unknown'.

    2568       expect(result.reason).toBe('Optimizely client is not initialized.');
                      ~~~~~~
    src/client.spec.ts:2593:73 - error TS2345: Argument of type '"test"' is not assignable to parameter of type 'keyof NotificationPayload'.

    2593       const notificationId = notificationCenter.addNotificationListener('test', () => {});
                                                                                 ~~~~~~


  ● Test suite failed to run

    src/hooks.spec.tsx:27:10 - error TS2305: Module '"@optimizely/optimizely-sdk"' has no exported member 'getLogger'.

    27 import { getLogger } from '@optimizely/optimizely-sdk';
                ~~~~~~~~~


  ● Test suite failed to run

    Vitest cannot be imported in a CommonJS module using require(). Please use "import" instead.

    If you are using "import" in your source code, then it's possible it was bundled into require() automatically by your bundler. In that case, do not bundle CommonJS output since it will never work with Vitest, or use dynamic import() which is available in all CommonJS modules.

      15 |  */
      16 |
    > 17 | import { vi, describe, it, expect } from 'vitest';
         | ^
      18 | import React, { useContext } from 'react';
      19 | import { render, waitFor, screen } from '@testing-library/react';
      20 | import type { Client as OptimizelyClient, OptimizelyUserContext } from '@optimizely/optimizely-sdk';

      at Object.<anonymous> (node_modules/vitest/index.cjs:1:7)
      at Object.<anonymous> (src/provider/OptimizelyProvider.spec.tsx:17:1)


  ● Test suite failed to run

    Vitest cannot be imported in a CommonJS module using require(). Please use "import" instead.

    If you are using "import" in your source code, then it's possible it was bundled into require() automatically by your bundler. In that case, do not bundle CommonJS output since it will never work with Vitest, or use dynamic import() which is available in all CommonJS modules.

      15 |  */
      16 |
    > 17 | import { vi, describe, it, expect, beforeEach } from 'vitest';
         | ^
      18 | import { ProviderStateStore } from './ProviderStateStore';
      19 |
      20 | describe('ProviderStateStore', () => {

      at Object.<anonymous> (node_modules/vitest/index.cjs:1:7)
      at Object.<anonymous> (src/provider/ProviderStateStore.spec.ts:17:1)


  ● Test suite failed to run

    TypeError: optimizely.getLogger is not a function

      18 | import { sprintf } from './utils';
      19 |
    > 20 | const logHandler = optimizely.getLogger('ReactSDK');
         |                               ^
      21 |
      22 | export const logger = {
      23 |   warn: (msg: string, ...splat: any[]) => {

      at Object.getLogger (src/logger.tsx:20:31)
      at Object.require (src/client.ts:21:1)
      at Object.require (src/Provider.tsx:21:1)
      at Object.<anonymous> (src/Feature.spec.tsx:24:1)


  ● Test suite failed to run

    TypeError: optimizely.getLogger is not a function

      18 | import { sprintf } from './utils';
      19 |
    > 20 | const logHandler = optimizely.getLogger('ReactSDK');
         |                               ^
      21 |
      22 | export const logger = {
      23 |   warn: (msg: string, ...splat: any[]) => {

      at Object.getLogger (src/logger.tsx:20:31)
      at Object.require (src/client.ts:21:1)
      at Object.require (src/hooks.ts:23:1)
      at Object.require (src/Experiment.tsx:20:1)
      at Object.<anonymous> (src/Experiment.spec.tsx:23:1)


  ● Test suite failed to run

    TypeError: optimizely.getLogger is not a function

      18 | import { sprintf } from './utils';
      19 |
    > 20 | const logHandler = optimizely.getLogger('ReactSDK');
         |                               ^
      21 |
      22 | export const logger = {
      23 |   warn: (msg: string, ...splat: any[]) => {

      at Object.getLogger (src/logger.tsx:20:31)
      at Object.require (src/client.ts:21:1)
      at Object.require (src/Provider.tsx:21:1)
      at Object.<anonymous> (src/withOptimizely.spec.tsx:23:1)


  ● Test suite failed to run

    src/Provider.spec.tsx:23:10 - error TS2305: Module '"@optimizely/optimizely-sdk"' has no exported member 'getLogger'.

    23 import { getLogger } from '@optimizely/optimizely-sdk';
                ~~~~~~~~~


  ● Test suite failed to run

    src/logger.spec.ts:36:37 - error TS2339: Property 'getLogger' does not exist on type 'typeof import("/home/runner/work/react-sdk/react-sdk/node_modules/@optimizely/optimizely-sdk/dist/index")'.

    36   const mockLogHandler = optimizely.getLogger('ReactSDK');
                                           ~~~~~~~~~
    src/logger.spec.ts:49:52 - error TS2339: Property 'enums' does not exist on type 'typeof import("/home/runner/work/react-sdk/react-sdk/node_modules/@optimizely/optimizely-sdk/dist/index")'.

    49     expect(logSpy).toHaveBeenCalledWith(optimizely.enums.LOG_LEVEL.WARNING, sprintf(message, arg));
                                                          ~~~~~
    src/logger.spec.ts:58:52 - error TS2339: Property 'enums' does not exist on type 'typeof import("/home/runner/work/react-sdk/react-sdk/node_modules/@optimizely/optimizely-sdk/dist/index")'.

    58     expect(logSpy).toHaveBeenCalledWith(optimizely.enums.LOG_LEVEL.INFO, sprintf(message, arg));
                                                          ~~~~~
    src/logger.spec.ts:67:52 - error TS2339: Property 'enums' does not exist on type 'typeof import("/home/runner/work/react-sdk/react-sdk/node_modules/@optimizely/optimizely-sdk/dist/index")'.

    67     expect(logSpy).toHaveBeenCalledWith(optimizely.enums.LOG_LEVEL.DEBUG, sprintf(message, arg));
                                                          ~~~~~
    src/logger.spec.ts:76:52 - error TS2339: Property 'enums' does not exist on type 'typeof import("/home/runner/work/react-sdk/react-sdk/node_modules/@optimizely/optimizely-sdk/dist/index")'.

    76     expect(logSpy).toHaveBeenCalledWith(optimizely.enums.LOG_LEVEL.ERROR, sprintf(message, arg));
                                                          ~~~~~


  ● Test suite failed to run

    src/logOnlyEventDispatcher.spec.ts:22:10 - error TS2305: Module '"@optimizely/optimizely-sdk"' has no exported member 'getLogger'.

    22 import { getLogger } from '@optimizely/optimizely-sdk';
                ~~~~~~~~~
    src/logOnlyEventDispatcher.spec.ts:34:53 - error TS2554: Expected 1 arguments, but got 2.

    34     logOnlyEventDispatcher.dispatchEvent(mockEvent, callback);
                                                           ~~~~~~~~
    src/logOnlyEventDispatcher.spec.ts:48:61 - error TS2554: Expected 1 arguments, but got 2.

    48     logOnlyEventDispatcher.dispatchEvent(circularReference, callback);
                                                                   ~~~~~~~~


  ● Test suite failed to run

    Vitest cannot be imported in a CommonJS module using require(). Please use "import" instead.

    If you are using "import" in your source code, then it's possible it was bundled into require() automatically by your bundler. In that case, do not bundle CommonJS output since it will never work with Vitest, or use dynamic import() which is available in all CommonJS modules.

      15 |  */
      16 |
    > 17 | import { vi, describe, it, expect, beforeEach, type MockedFunction } from 'vitest';
         | ^
      18 | import { createInstance as jsCreateInstance } from '@optimizely/optimizely-sdk';
      19 | import type { Config } from '@optimizely/optimizely-sdk';
      20 | import { createInstance, CLIENT_ENGINE, CLIENT_VERSION } from './createInstance';

      at Object.<anonymous> (node_modules/vitest/index.cjs:1:7)
      at Object.<anonymous> (src/client/client.spec.ts:17:1)

Report generated by 🧪jest coverage report action from 86fc59f

@junaed-optimizely junaed-optimizely merged commit 8e43d1f into master Jan 30, 2026
9 of 10 checks passed
@junaed-optimizely junaed-optimizely deleted the junaed/fssdk-12249-provider-impl branch January 30, 2026 16:30
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.

3 participants