From ead003ba3abb146a776bf57ed0e8f76e4283e648 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Mon, 22 Dec 2025 12:47:04 -0300 Subject: [PATCH 1/3] Complete the mapping of SplitConfiguration (Flutter SDK config) to JS SDK configuration object --- .github/workflows/test.yml | 2 + .../lib/split_configuration.dart | 8 +- splitio_web/lib/splitio_web.dart | 218 +++++++++++++++- splitio_web/lib/src/js_interop.dart | 19 +- splitio_web/test/splitio_web_test.dart | 240 ++++++++++++++++++ .../test/utils/js_interop_test_utils.dart | 34 +++ 6 files changed, 510 insertions(+), 11 deletions(-) create mode 100644 splitio_web/test/splitio_web_test.dart create mode 100644 splitio_web/test/utils/js_interop_test_utils.dart diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index eb7e486..3a4a238 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,3 +25,5 @@ jobs: run: cd splitio_android/; flutter test - name: Run flutter splitio_ios test run: cd splitio_ios/; flutter test + - name: Run flutter splitio_web test + run: cd splitio_web/; flutter test --platform=chrome diff --git a/splitio_platform_interface/lib/split_configuration.dart b/splitio_platform_interface/lib/split_configuration.dart index ffe9a9d..1d54fdd 100644 --- a/splitio_platform_interface/lib/split_configuration.dart +++ b/splitio_platform_interface/lib/split_configuration.dart @@ -21,7 +21,7 @@ class SplitConfiguration { /// /// [eventFlushInterval] When using .track, how often the events queue is flushed to Split servers. /// - /// [eventsPerPush] Maximum size of the batch to push events. + /// [eventsPerPush] Maximum size of the batch to push events. Not supported in Web. /// /// [trafficType] The default traffic type for events tracked using the track method. If not specified, every track call should specify a traffic type. /// @@ -29,7 +29,7 @@ class SplitConfiguration { /// /// [streamingEnabled] Boolean flag to enable the streaming service as default synchronization mechanism when in foreground. In the event of an issue with streaming, the SDK will fallback to the polling mechanism. If false, the SDK will poll for changes as usual without attempting to use streaming. /// - /// [persistentAttributesEnabled] Enables saving attributes on persistent cache which is loaded as part of the SDK_READY_FROM_CACHE flow. All functions that mutate the stored attributes map affect the persistent cache. + /// [persistentAttributesEnabled] Enables saving attributes on persistent cache which is loaded as part of the SDK_READY_FROM_CACHE flow. All functions that mutate the stored attributes map affect the persistent cache. Not supported in Web. /// /// [impressionListener] Enables impression listener. If true, generated impressions will be streamed in the impressionsStream() method of Splitio. /// @@ -41,13 +41,13 @@ class SplitConfiguration { /// /// [userConsent] User consent status used to control the tracking of events and impressions. Possible values are [UserConsent.granted], [UserConsent.declined], and [UserConsent.unknown]. /// - /// [encryptionEnabled] If set to true, the local database contents is encrypted. Defaults to false. + /// [encryptionEnabled] If set to true, the local database contents is encrypted. Defaults to false. Not supported in Web. /// /// [logLevel] Enables logging according to the level specified. Options are [SplitLogLevel.verbose], [SplitLogLevel.none], [SplitLogLevel.debug], [SplitLogLevel.info], [SplitLogLevel.warning], and [SplitLogLevel.error]. /// /// [readyTimeout] Maximum amount of time in seconds to wait before firing the SDK_READY_TIMED_OUT event. Defaults to 10 seconds. /// - /// [certificatePinningConfiguration] Certificate pinning configuration. Pins need to have the format of a base64 SHA-256 or base64 SHA-1 hashes of the SPKI (ex.: "sha256/7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y="). + /// [certificatePinningConfiguration] Certificate pinning configuration. Pins need to have the format of a base64 SHA-256 or base64 SHA-1 hashes of the SPKI (ex.: "sha256/7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y="). Not supported in Web. SplitConfiguration({ int? featuresRefreshRate, int? segmentsRefreshRate, diff --git a/splitio_web/lib/splitio_web.dart b/splitio_web/lib/splitio_web.dart index cc9bdfb..d175b7d 100644 --- a/splitio_web/lib/splitio_web.dart +++ b/splitio_web/lib/splitio_web.dart @@ -22,6 +22,8 @@ class SplitioWeb extends SplitioPlatform { Future? _initFuture; late JS_IBrowserSDK _factory; + String? _trafficType; + bool _impressionListener = false; @override Future init({ @@ -49,6 +51,33 @@ class SplitioWeb extends SplitioPlatform { // Create factory instance this._factory = window.splitio!.SplitFactory.callAsFunction(null, config) as JS_IBrowserSDK; + if (sdkConfiguration != null) { + if (sdkConfiguration.configurationMap['trafficType'] is String) { + this._trafficType = sdkConfiguration.configurationMap['trafficType']; + } + + if (sdkConfiguration.configurationMap['impressionListener'] is bool) { + this._impressionListener = + sdkConfiguration.configurationMap['impressionListener']; + } + + // Log warnings regarding unsupported configs. Not done in _buildConfig to reuse the factory logger + final unsupportedConfigs = [ + 'encryptionEnabled', + 'certificatePinningConfiguration', + 'persistentAttributesEnabled', + 'eventsPerPush' + ]; + for (final configName in unsupportedConfigs) { + if (sdkConfiguration.configurationMap[configName] != null) { + this._factory.settings.log.warn.callAsFunction( + this._factory.settings.log, + 'Config $configName is not supported by the Web package. This config will be ignored.' + .toJS); + } + } + } + return; } @@ -85,17 +114,194 @@ class SplitioWeb extends SplitioPlatform { } // Map SplitConfiguration to JS equivalent object - JSObject _buildConfig(String apiKey, String matchingKey, String? bucketingKey, SplitConfiguration? configuration) { + static JSObject _buildConfig(String apiKey, String matchingKey, String? bucketingKey, SplitConfiguration? configuration) { + final config = JSObject(); + final core = JSObject(); core.setProperty('authorizationKey'.toJS, apiKey.toJS); - // @TODO: set bucketingKey if provided - core.setProperty('key'.toJS, matchingKey.toJS); - - final config = JSObject(); + core.setProperty('key'.toJS, _buildKey(matchingKey, bucketingKey)); config.setProperty('core'.toJS, core); - // @TODO: complete config + if (configuration != null) { + final scheduler = JSObject(); + if (configuration.configurationMap.containsKey('featuresRefreshRate')) + scheduler.setProperty( + 'featuresRefreshRate'.toJS, + (configuration.configurationMap['featuresRefreshRate'] as int) + .toJS); + if (configuration.configurationMap.containsKey('segmentsRefreshRate')) + scheduler.setProperty( + 'segmentsRefreshRate'.toJS, + (configuration.configurationMap['segmentsRefreshRate'] as int) + .toJS); + if (configuration.configurationMap.containsKey('impressionsRefreshRate')) + scheduler.setProperty( + 'impressionsRefreshRate'.toJS, + (configuration.configurationMap['impressionsRefreshRate'] as int) + .toJS); + if (configuration.configurationMap.containsKey('telemetryRefreshRate')) + scheduler.setProperty( + 'telemetryRefreshRate'.toJS, + (configuration.configurationMap['telemetryRefreshRate'] as int) + .toJS); + if (configuration.configurationMap.containsKey('eventsQueueSize')) + scheduler.setProperty('eventsQueueSize'.toJS, + (configuration.configurationMap['eventsQueueSize'] as int).toJS); + if (configuration.configurationMap.containsKey('impressionsQueueSize')) + scheduler.setProperty( + 'impressionsQueueSize'.toJS, + (configuration.configurationMap['impressionsQueueSize'] as int) + .toJS); + if (configuration.configurationMap.containsKey('eventFlushInterval')) + scheduler.setProperty('eventsPushRate'.toJS, + (configuration.configurationMap['eventFlushInterval'] as int).toJS); + config.setProperty('scheduler'.toJS, scheduler); + + if (configuration.configurationMap.containsKey('streamingEnabled')) + config.setProperty('streamingEnabled'.toJS, + (configuration.configurationMap['streamingEnabled'] as bool).toJS); + + final urls = JSObject(); + if (configuration.configurationMap.containsKey('sdkEndpoint')) + urls.setProperty('sdk'.toJS, + (configuration.configurationMap['sdkEndpoint'] as String).toJS); + if (configuration.configurationMap.containsKey('eventsEndpoint')) + urls.setProperty('events'.toJS, + (configuration.configurationMap['eventsEndpoint'] as String).toJS); + if (configuration.configurationMap.containsKey('authServiceEndpoint')) + urls.setProperty( + 'auth'.toJS, + (configuration.configurationMap['authServiceEndpoint'] as String) + .toJS); + if (configuration.configurationMap + .containsKey('streamingServiceEndpoint')) + urls.setProperty( + 'streaming'.toJS, + (configuration.configurationMap['streamingServiceEndpoint'] + as String) + .toJS); + if (configuration.configurationMap + .containsKey('telemetryServiceEndpoint')) + urls.setProperty( + 'telemetry'.toJS, + (configuration.configurationMap['telemetryServiceEndpoint'] + as String) + .toJS); + config.setProperty('urls'.toJS, urls); + + final sync = JSObject(); + if (configuration.configurationMap['impressionsMode'] != null) { + sync.setProperty( + 'impressionsMode'.toJS, + (configuration.configurationMap['impressionsMode'] as String) + .toUpperCase() + .toJS); + } + + if (configuration.configurationMap['syncEnabled'] != null) { + sync.setProperty('enabled'.toJS, + (configuration.configurationMap['syncEnabled'] as bool).toJS); + } + + if (configuration.configurationMap['syncConfig'] != null) { + final syncConfig = configuration.configurationMap['syncConfig'] + as Map>; + final List> splitFilters = []; + + if (syncConfig['syncConfigNames'] != null && + syncConfig['syncConfigNames']!.isNotEmpty) { + splitFilters + .add({'type': 'byName', 'values': syncConfig['syncConfigNames']}); + } + + if (syncConfig['syncConfigPrefixes'] != null && + syncConfig['syncConfigPrefixes']!.isNotEmpty) { + splitFilters.add( + {'type': 'byPrefix', 'values': syncConfig['syncConfigPrefixes']}); + } + + if (syncConfig['syncConfigFlagSets'] != null && + syncConfig['syncConfigFlagSets']!.isNotEmpty) { + splitFilters.add( + {'type': 'bySet', 'values': syncConfig['syncConfigFlagSets']}); + } + sync.setProperty('splitFilters'.toJS, splitFilters.jsify()); + } + config.setProperty('sync'.toJS, sync); + + if (configuration.configurationMap['userConsent'] != null) { + config.setProperty( + 'userConsent'.toJS, + (configuration.configurationMap['userConsent'] as String) + .toUpperCase() + .toJS); + } + + final logLevel = configuration.configurationMap['logLevel']; + if (logLevel is String) { + final logger = logLevel == SplitLogLevel.verbose.toString() || + logLevel == SplitLogLevel.debug.toString() + ? window.splitio!.DebugLogger?.callAsFunction(null) + : logLevel == SplitLogLevel.info.toString() + ? window.splitio!.InfoLogger?.callAsFunction(null) + : logLevel == SplitLogLevel.warning.toString() + ? window.splitio!.WarnLogger?.callAsFunction(null) + : logLevel == SplitLogLevel.error.toString() + ? window.splitio!.ErrorLogger?.callAsFunction(null) + : null; + if (logger != null) { + config.setProperty('debug'.toJS, logger); // Browser SDK + } else { + config.setProperty( + 'debug'.toJS, logLevel.toUpperCase().toJS); // JS SDK + } + } else if (configuration.configurationMap['enableDebug'] == true) { + config.setProperty( + 'debug'.toJS, window.splitio!.DebugLogger?.callAsFunction(null)); + } + + if (configuration.configurationMap['readyTimeout'] != null) { + final startup = JSObject(); + startup.setProperty('readyTimeout'.toJS, + (configuration.configurationMap['readyTimeout'] as int).toJS); + config.setProperty('startup'.toJS, startup); + } + + final storageOptions = JSObject(); + storageOptions.setProperty('type'.toJS, 'LOCALSTORAGE'.toJS); + if (configuration.configurationMap['rolloutCacheConfiguration'] != null) { + final rolloutCacheConfiguration = + configuration.configurationMap['rolloutCacheConfiguration'] + as Map; + if (rolloutCacheConfiguration['expirationDays'] != null) { + storageOptions.setProperty('expirationDays'.toJS, + (rolloutCacheConfiguration['expirationDays'] as int).toJS); + } + if (rolloutCacheConfiguration['clearOnInit'] != null) { + storageOptions.setProperty('clearOnInit'.toJS, + (rolloutCacheConfiguration['clearOnInit'] as bool).toJS); + } + } + if (window.splitio!.InLocalStorage != null) { + config.setProperty( + 'storage'.toJS, + window.splitio!.InLocalStorage + ?.callAsFunction(null, storageOptions)); // Browser SDK + } else { + config.setProperty('storage'.toJS, storageOptions); // JS SDK + } + } + return config; } + static JSAny _buildKey(String matchingKey, String? bucketingKey) { + if (bucketingKey != null) { + final splitKey = JSObject(); + splitKey.setProperty('matchingKey'.toJS, matchingKey.toJS); + splitKey.setProperty('bucketingKey'.toJS, bucketingKey.toJS); + return splitKey; + } + return matchingKey.toJS; + } } diff --git a/splitio_web/lib/src/js_interop.dart b/splitio_web/lib/src/js_interop.dart index 28192c0..fd65946 100644 --- a/splitio_web/lib/src/js_interop.dart +++ b/splitio_web/lib/src/js_interop.dart @@ -1,9 +1,26 @@ import 'dart:js_interop'; @JS() -extension type JS_IBrowserSDK._(JSObject _) implements JSObject {} +extension type JS_Logger._(JSObject _) implements JSObject { + external JSFunction warn; +} + +@JS() +extension type JS_ISettings._(JSObject _) implements JSObject { + external JS_Logger log; +} + +@JS() +extension type JS_IBrowserSDK._(JSObject _) implements JSObject { + external JS_ISettings settings; +} @JS() extension type JS_BrowserSDKPackage._(JSObject _) implements JSObject { external JSFunction SplitFactory; + external JSFunction? InLocalStorage; + external JSFunction? DebugLogger; + external JSFunction? InfoLogger; + external JSFunction? WarnLogger; + external JSFunction? ErrorLogger; } diff --git a/splitio_web/test/splitio_web_test.dart b/splitio_web/test/splitio_web_test.dart new file mode 100644 index 0000000..5c3dafe --- /dev/null +++ b/splitio_web/test/splitio_web_test.dart @@ -0,0 +1,240 @@ +import 'dart:js_interop'; +import 'dart:js_interop_unsafe'; +import 'package:web/web.dart' as web; +import 'package:flutter_test/flutter_test.dart'; +import 'package:splitio_web/splitio_web.dart'; +import 'package:splitio_web/src/js_interop.dart'; +import 'package:splitio_platform_interface/split_configuration.dart'; +import 'package:splitio_platform_interface/split_sync_config.dart'; +import 'package:splitio_platform_interface/split_rollout_cache_configuration.dart'; +import 'utils/js_interop_test_utils.dart'; + +extension on web.Window { + @JS() + external JS_BrowserSDKPackage? splitio; +} + +void main() { + String methodName = ''; + dynamic methodArguments; + + setUp(() { + final mockFactory = JSObject(); + + final mockSplitio = JSObject(); + mockSplitio['SplitFactory'] = (JSAny? arg1) { + methodName = 'SplitFactory'; + methodArguments = [arg1]; + return mockFactory; + }.toJS; + + (web.window as JSObject).setProperty('splitio'.toJS, mockSplitio); + }); + + group('initialization', () { + test('init with matching key only', () async { + SplitioWeb _platform = SplitioWeb(); + + await _platform.init( + apiKey: 'api-key', matchingKey: 'matching-key', bucketingKey: null); + + expect(methodName, 'SplitFactory'); + expect( + jsObjectToMap(methodArguments[0]), + equals({ + 'core': { + 'authorizationKey': 'api-key', + 'key': 'matching-key', + } + })); + }); + + test('init with bucketing key', () async { + SplitioWeb _platform = SplitioWeb(); + + await _platform.init( + apiKey: 'api-key', + matchingKey: 'matching-key', + bucketingKey: 'bucketing-key'); + + expect(methodName, 'SplitFactory'); + expect( + jsObjectToMap(methodArguments[0]), + equals({ + 'core': { + 'authorizationKey': 'api-key', + 'key': { + 'matchingKey': 'matching-key', + 'bucketingKey': 'bucketing-key', + }, + } + })); + }); + + test('init with config: empty config', () async { + SplitioWeb _platform = SplitioWeb(); + + await _platform.init( + apiKey: 'api-key', + matchingKey: 'matching-key', + bucketingKey: 'bucketing-key', + sdkConfiguration: SplitConfiguration()); + + expect(methodName, 'SplitFactory'); + expect( + jsObjectToMap(methodArguments[0]), + equals({ + 'core': { + 'authorizationKey': 'api-key', + 'key': { + 'matchingKey': 'matching-key', + 'bucketingKey': 'bucketing-key', + }, + }, + 'startup': { + 'readyTimeout': 10, + }, + 'scheduler': {}, + 'urls': {}, + 'sync': {}, + 'storage': {'type': 'LOCALSTORAGE'} + })); + }); + + // @TODO validate warning for unsupported config options + // @TODO validate full config with pluggable Browser SDK modules + test('init with config: full config', () async { + SplitioWeb _platform = SplitioWeb(); + + await _platform.init( + apiKey: 'api-key', + matchingKey: 'matching-key', + bucketingKey: 'bucketing-key', + sdkConfiguration: SplitConfiguration( + featuresRefreshRate: 1, + segmentsRefreshRate: 2, + impressionsRefreshRate: 3, + telemetryRefreshRate: 4, + eventsQueueSize: 5, + impressionsQueueSize: 6, + eventFlushInterval: 7, + // eventsPerPush: 8, // unsupported in Web + trafficType: 'user', + enableDebug: false, // deprecated, logLevel has precedence + streamingEnabled: false, + // persistentAttributesEnabled: true, // unsupported in Web + impressionListener: true, + sdkEndpoint: 'sdk-endpoint', + eventsEndpoint: 'events-endpoint', + authServiceEndpoint: 'auth-service-endpoint', + streamingServiceEndpoint: 'streaming-service-endpoint', + telemetryServiceEndpoint: 'telemetry-service-endpoint', + syncConfig: SyncConfig( + names: ['flag_1', 'flag_2'], prefixes: ['prefix_1']), + impressionsMode: ImpressionsMode.none, + syncEnabled: true, + userConsent: UserConsent.granted, + // encryptionEnabled: true, // unsupported in Web + logLevel: SplitLogLevel.info, + readyTimeout: 1, + // certificatePinningConfiguration: + // CertificatePinningConfiguration(), // unsupported in Web + rolloutCacheConfiguration: RolloutCacheConfiguration( + expirationDays: 100, + clearOnInit: true, + ))); + + expect(methodName, 'SplitFactory'); + expect( + jsObjectToMap(methodArguments[0]), + equals({ + 'core': { + 'authorizationKey': 'api-key', + 'key': { + 'matchingKey': 'matching-key', + 'bucketingKey': 'bucketing-key', + }, + }, + 'streamingEnabled': false, + 'startup': { + 'readyTimeout': 1, + }, + 'debug': 'INFO', + 'scheduler': { + 'featuresRefreshRate': 1, + 'segmentsRefreshRate': 2, + 'impressionsRefreshRate': 3, + 'telemetryRefreshRate': 4, + 'eventsQueueSize': 5, + 'impressionsQueueSize': 6, + 'eventsPushRate': 7, + }, + 'urls': { + 'sdk': 'sdk-endpoint', + 'events': 'events-endpoint', + 'auth': 'auth-service-endpoint', + 'streaming': 'streaming-service-endpoint', + 'telemetry': 'telemetry-service-endpoint', + }, + 'sync': { + 'impressionsMode': 'NONE', + 'enabled': true, + 'splitFilters': [ + { + 'type': 'byName', + 'values': ['flag_1', 'flag_2'] + }, + { + 'type': 'byPrefix', + 'values': ['prefix_1'] + } + ] + }, + 'userConsent': 'GRANTED', + 'storage': { + 'type': 'LOCALSTORAGE', + 'expirationDays': 100, + 'clearOnInit': true + } + })); + }); + + test('init with config: SyncConfig.flagSets', () async { + SplitioWeb _platform = SplitioWeb(); + + await _platform.init( + apiKey: 'api-key', + matchingKey: 'matching-key', + bucketingKey: 'bucketing-key', + sdkConfiguration: SplitConfiguration( + syncConfig: SyncConfig.flagSets(['flag_set_1', 'flag_set_2']))); + + expect(methodName, 'SplitFactory'); + expect( + jsObjectToMap(methodArguments[0]), + equals({ + 'core': { + 'authorizationKey': 'api-key', + 'key': { + 'matchingKey': 'matching-key', + 'bucketingKey': 'bucketing-key', + }, + }, + 'startup': { + 'readyTimeout': 10, + }, + 'scheduler': {}, + 'urls': {}, + 'sync': { + 'splitFilters': [ + { + 'type': 'bySet', + 'values': ['flag_set_1', 'flag_set_2'] + } + ] + }, + 'storage': {'type': 'LOCALSTORAGE'} + })); + }); + }); +} diff --git a/splitio_web/test/utils/js_interop_test_utils.dart b/splitio_web/test/utils/js_interop_test_utils.dart new file mode 100644 index 0000000..153e627 --- /dev/null +++ b/splitio_web/test/utils/js_interop_test_utils.dart @@ -0,0 +1,34 @@ +import 'dart:js_interop'; + +@JS('Object.keys') +external JSArray _objectKeys(JSObject obj); + +@JS('Reflect.get') +external JSAny? _reflectGet(JSObject target, JSAny propertyKey); + +List jsArrayToList(JSArray obj) { + return obj.toDart.map(jsAnyToDart).toList(); +} + +Map jsObjectToMap(JSObject obj) { + return { + for (final jsKey in _objectKeys(obj).toDart) + jsKey.toDart: jsAnyToDart(_reflectGet(obj, jsKey)), + }; +} + +dynamic jsAnyToDart(JSAny? value) { + if (value is JSArray) { + return jsArrayToList(value); + } else if (value is JSObject) { + return jsObjectToMap(value); + } else if (value is JSString) { + return value.toDart; + } else if (value is JSNumber) { + return value.toDartInt; + } else if (value is JSBoolean) { + return value.toDart; + } else { + return value; // JS null and undefined are null in Dart + } +} From bf7ab850874c6802d352c6b92b23a904e195d046 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Mon, 22 Dec 2025 12:54:42 -0300 Subject: [PATCH 2/3] Linter --- splitio_web/lib/splitio_web.dart | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/splitio_web/lib/splitio_web.dart b/splitio_web/lib/splitio_web.dart index d175b7d..28e4459 100644 --- a/splitio_web/lib/splitio_web.dart +++ b/splitio_web/lib/splitio_web.dart @@ -33,7 +33,11 @@ class SplitioWeb extends SplitioPlatform { SplitConfiguration? sdkConfiguration, }) async { if (_initFuture == null) { - _initFuture = this._init(apiKey: apiKey, matchingKey: matchingKey, bucketingKey: bucketingKey, sdkConfiguration: sdkConfiguration); + _initFuture = this._init( + apiKey: apiKey, + matchingKey: matchingKey, + bucketingKey: bucketingKey, + sdkConfiguration: sdkConfiguration); } return _initFuture; } @@ -46,10 +50,12 @@ class SplitioWeb extends SplitioPlatform { }) async { await _loadSplitSdk(); - final config = _buildConfig(apiKey, matchingKey, bucketingKey, sdkConfiguration); + final config = + _buildConfig(apiKey, matchingKey, bucketingKey, sdkConfiguration); // Create factory instance - this._factory = window.splitio!.SplitFactory.callAsFunction(null, config) as JS_IBrowserSDK; + this._factory = window.splitio!.SplitFactory.callAsFunction(null, config) + as JS_IBrowserSDK; if (sdkConfiguration != null) { if (sdkConfiguration.configurationMap['trafficType'] is String) { @@ -114,7 +120,8 @@ class SplitioWeb extends SplitioPlatform { } // Map SplitConfiguration to JS equivalent object - static JSObject _buildConfig(String apiKey, String matchingKey, String? bucketingKey, SplitConfiguration? configuration) { + static JSObject _buildConfig(String apiKey, String matchingKey, + String? bucketingKey, SplitConfiguration? configuration) { final config = JSObject(); final core = JSObject(); From 4400f260056b7d0ae964489474879e6b26da984e Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Mon, 22 Dec 2025 14:00:01 -0300 Subject: [PATCH 3/3] Remove code for unsupported configs --- splitio_web/lib/splitio_web.dart | 16 ---------------- splitio_web/lib/src/js_interop.dart | 11 ----------- 2 files changed, 27 deletions(-) diff --git a/splitio_web/lib/splitio_web.dart b/splitio_web/lib/splitio_web.dart index 28e4459..7a3ad91 100644 --- a/splitio_web/lib/splitio_web.dart +++ b/splitio_web/lib/splitio_web.dart @@ -66,22 +66,6 @@ class SplitioWeb extends SplitioPlatform { this._impressionListener = sdkConfiguration.configurationMap['impressionListener']; } - - // Log warnings regarding unsupported configs. Not done in _buildConfig to reuse the factory logger - final unsupportedConfigs = [ - 'encryptionEnabled', - 'certificatePinningConfiguration', - 'persistentAttributesEnabled', - 'eventsPerPush' - ]; - for (final configName in unsupportedConfigs) { - if (sdkConfiguration.configurationMap[configName] != null) { - this._factory.settings.log.warn.callAsFunction( - this._factory.settings.log, - 'Config $configName is not supported by the Web package. This config will be ignored.' - .toJS); - } - } } return; diff --git a/splitio_web/lib/src/js_interop.dart b/splitio_web/lib/src/js_interop.dart index fd65946..312f50e 100644 --- a/splitio_web/lib/src/js_interop.dart +++ b/splitio_web/lib/src/js_interop.dart @@ -1,18 +1,7 @@ import 'dart:js_interop'; -@JS() -extension type JS_Logger._(JSObject _) implements JSObject { - external JSFunction warn; -} - -@JS() -extension type JS_ISettings._(JSObject _) implements JSObject { - external JS_Logger log; -} - @JS() extension type JS_IBrowserSDK._(JSObject _) implements JSObject { - external JS_ISettings settings; } @JS()