From c1ad120d653e33b633234f9fa05e13a494c01ad9 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 13 Jan 2026 12:22:33 -0300 Subject: [PATCH 01/13] Add FallbackTreatmentsConfiguration support to SplitConfiguration --- .../lib/split_configuration.dart | 13 +++++++++++ ...lit_fallback_treatments_configuration.dart | 18 +++++++++++++++ ...allback_treatments_configuration_test.dart | 23 +++++++++++++++++++ .../test/splitio_configuration_test.dart | 7 +++++- 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 splitio_platform_interface/lib/split_fallback_treatments_configuration.dart create mode 100644 splitio_platform_interface/test/split_fallback_treatments_configuration_test.dart diff --git a/splitio_platform_interface/lib/split_configuration.dart b/splitio_platform_interface/lib/split_configuration.dart index 1d54fdd..4a0400a 100644 --- a/splitio_platform_interface/lib/split_configuration.dart +++ b/splitio_platform_interface/lib/split_configuration.dart @@ -1,4 +1,5 @@ import 'package:splitio_platform_interface/split_certificate_pinning_configuration.dart'; +import 'package:splitio_platform_interface/split_fallback_treatments_configuration.dart'; import 'package:splitio_platform_interface/split_sync_config.dart'; import 'package:splitio_platform_interface/split_rollout_cache_configuration.dart'; @@ -48,6 +49,10 @@ class SplitConfiguration { /// [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="). Not supported in Web. + /// + /// [rolloutCacheConfiguration] Rollout cache configuration. + /// + /// [fallbackTreatmentsConfiguration] Fallback treatments configuration. SplitConfiguration({ int? featuresRefreshRate, int? segmentsRefreshRate, @@ -76,6 +81,7 @@ class SplitConfiguration { int? readyTimeout = 10, CertificatePinningConfiguration? certificatePinningConfiguration, RolloutCacheConfiguration? rolloutCacheConfiguration, + FallbackTreatmentsConfiguration? fallbackTreatmentsConfiguration, }) { if (featuresRefreshRate != null) { configurationMap['featuresRefreshRate'] = featuresRefreshRate; @@ -195,6 +201,13 @@ class SplitConfiguration { 'clearOnInit': rolloutCacheConfiguration.clearOnInit }; } + + if (fallbackTreatmentsConfiguration != null) { + configurationMap['fallbackTreatmentsConfiguration'] = { + 'global': fallbackTreatmentsConfiguration.global, + 'byFlag': fallbackTreatmentsConfiguration.byFlag + }; + } } } diff --git a/splitio_platform_interface/lib/split_fallback_treatments_configuration.dart b/splitio_platform_interface/lib/split_fallback_treatments_configuration.dart new file mode 100644 index 0000000..53abefa --- /dev/null +++ b/splitio_platform_interface/lib/split_fallback_treatments_configuration.dart @@ -0,0 +1,18 @@ +import 'package:splitio_platform_interface/split_result.dart'; + +class FallbackTreatmentsConfiguration { + late Map? _global; + late Map>? _byFlag; + + Map? get global => _global; + Map>? get byFlag => _byFlag; + + FallbackTreatmentsConfiguration( + {SplitResult? global, Map? byFlag}) { + _global = global != null + ? {'treatment': global.treatment, 'config': global.config} + : null; + _byFlag = byFlag?.map((key, value) => + MapEntry(key, {'treatment': value.treatment, 'config': value.config})); + } +} diff --git a/splitio_platform_interface/test/split_fallback_treatments_configuration_test.dart b/splitio_platform_interface/test/split_fallback_treatments_configuration_test.dart new file mode 100644 index 0000000..b520b56 --- /dev/null +++ b/splitio_platform_interface/test/split_fallback_treatments_configuration_test.dart @@ -0,0 +1,23 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:splitio_platform_interface/split_fallback_treatments_configuration.dart'; +import 'package:splitio_platform_interface/split_result.dart'; + +void main() { + test('global and by flag fallback treatments', () { + var config = FallbackTreatmentsConfiguration(global: const SplitResult('custom-treatment', null)); + + expect(config.global, equals({'treatment': 'custom-treatment', 'config': null})); + expect(config.byFlag, null); + + config = FallbackTreatmentsConfiguration(byFlag: {'flag1': const SplitResult('custom-treatment', 'custom-config')}); + expect(config.byFlag, equals({'flag1': {'treatment': 'custom-treatment', 'config': 'custom-config'}})); + expect(config.global, null); + }); + + test('default values', () { + var config = FallbackTreatmentsConfiguration(); + + expect(config.global, null); + expect(config.byFlag, null); + }); +} \ No newline at end of file diff --git a/splitio_platform_interface/test/splitio_configuration_test.dart b/splitio_platform_interface/test/splitio_configuration_test.dart index 64b758c..0f740d4 100644 --- a/splitio_platform_interface/test/splitio_configuration_test.dart +++ b/splitio_platform_interface/test/splitio_configuration_test.dart @@ -1,6 +1,8 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:splitio_platform_interface/split_certificate_pinning_configuration.dart'; import 'package:splitio_platform_interface/split_configuration.dart'; +import 'package:splitio_platform_interface/split_fallback_treatments_configuration.dart'; +import 'package:splitio_platform_interface/split_result.dart'; import 'package:splitio_platform_interface/split_rollout_cache_configuration.dart'; import 'package:splitio_platform_interface/split_sync_config.dart'; @@ -36,7 +38,8 @@ void main() { .addPin('host1', 'pin1') .addPin('host2', 'pin3') .addPin('host1', 'pin2'), - rolloutCacheConfiguration: RolloutCacheConfiguration(expirationDays: 15, clearOnInit: true)); + rolloutCacheConfiguration: RolloutCacheConfiguration(expirationDays: 15, clearOnInit: true), + fallbackTreatmentsConfiguration: FallbackTreatmentsConfiguration(global: const SplitResult('custom-treatment', null))); expect(config.configurationMap['eventFlushInterval'], 2000); expect(config.configurationMap['eventsPerPush'], 300); @@ -75,6 +78,8 @@ void main() { }); expect(config.configurationMap['rolloutCacheConfiguration']['expirationDays'], 15); expect(config.configurationMap['rolloutCacheConfiguration']['clearOnInit'], true); + expect(config.configurationMap['fallbackTreatmentsConfiguration']['global'], equals({'treatment': 'custom-treatment', 'config': null})); + expect(config.configurationMap['fallbackTreatmentsConfiguration']['byFlag'], null); }); test('no special values leaves map empty', () async { From 52a8cf8649d53ac7bbe8612123952ad4e77cff6d Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Fri, 16 Jan 2026 17:13:31 -0300 Subject: [PATCH 02/13] Rename config --- .../lib/split_configuration.dart | 14 +++++++------- ...uration.dart => split_fallback_treatments.dart} | 4 ++-- ...st.dart => split_fallback_treatments_test.dart} | 8 ++++---- .../test/splitio_configuration_test.dart | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) rename splitio_platform_interface/lib/{split_fallback_treatments_configuration.dart => split_fallback_treatments.dart} (88%) rename splitio_platform_interface/test/{split_fallback_treatments_configuration_test.dart => split_fallback_treatments_test.dart} (67%) diff --git a/splitio_platform_interface/lib/split_configuration.dart b/splitio_platform_interface/lib/split_configuration.dart index 4a0400a..28ee406 100644 --- a/splitio_platform_interface/lib/split_configuration.dart +++ b/splitio_platform_interface/lib/split_configuration.dart @@ -1,5 +1,5 @@ import 'package:splitio_platform_interface/split_certificate_pinning_configuration.dart'; -import 'package:splitio_platform_interface/split_fallback_treatments_configuration.dart'; +import 'package:splitio_platform_interface/split_fallback_treatments.dart'; import 'package:splitio_platform_interface/split_sync_config.dart'; import 'package:splitio_platform_interface/split_rollout_cache_configuration.dart'; @@ -52,7 +52,7 @@ class SplitConfiguration { /// /// [rolloutCacheConfiguration] Rollout cache configuration. /// - /// [fallbackTreatmentsConfiguration] Fallback treatments configuration. + /// [fallbackTreatments] Fallback treatments configuration. SplitConfiguration({ int? featuresRefreshRate, int? segmentsRefreshRate, @@ -81,7 +81,7 @@ class SplitConfiguration { int? readyTimeout = 10, CertificatePinningConfiguration? certificatePinningConfiguration, RolloutCacheConfiguration? rolloutCacheConfiguration, - FallbackTreatmentsConfiguration? fallbackTreatmentsConfiguration, + FallbackTreatments? fallbackTreatments, }) { if (featuresRefreshRate != null) { configurationMap['featuresRefreshRate'] = featuresRefreshRate; @@ -202,10 +202,10 @@ class SplitConfiguration { }; } - if (fallbackTreatmentsConfiguration != null) { - configurationMap['fallbackTreatmentsConfiguration'] = { - 'global': fallbackTreatmentsConfiguration.global, - 'byFlag': fallbackTreatmentsConfiguration.byFlag + if (fallbackTreatments != null) { + configurationMap['fallbackTreatments'] = { + 'global': fallbackTreatments.global, + 'byFlag': fallbackTreatments.byFlag }; } } diff --git a/splitio_platform_interface/lib/split_fallback_treatments_configuration.dart b/splitio_platform_interface/lib/split_fallback_treatments.dart similarity index 88% rename from splitio_platform_interface/lib/split_fallback_treatments_configuration.dart rename to splitio_platform_interface/lib/split_fallback_treatments.dart index 53abefa..5a46c35 100644 --- a/splitio_platform_interface/lib/split_fallback_treatments_configuration.dart +++ b/splitio_platform_interface/lib/split_fallback_treatments.dart @@ -1,13 +1,13 @@ import 'package:splitio_platform_interface/split_result.dart'; -class FallbackTreatmentsConfiguration { +class FallbackTreatments { late Map? _global; late Map>? _byFlag; Map? get global => _global; Map>? get byFlag => _byFlag; - FallbackTreatmentsConfiguration( + FallbackTreatments( {SplitResult? global, Map? byFlag}) { _global = global != null ? {'treatment': global.treatment, 'config': global.config} diff --git a/splitio_platform_interface/test/split_fallback_treatments_configuration_test.dart b/splitio_platform_interface/test/split_fallback_treatments_test.dart similarity index 67% rename from splitio_platform_interface/test/split_fallback_treatments_configuration_test.dart rename to splitio_platform_interface/test/split_fallback_treatments_test.dart index b520b56..95914d3 100644 --- a/splitio_platform_interface/test/split_fallback_treatments_configuration_test.dart +++ b/splitio_platform_interface/test/split_fallback_treatments_test.dart @@ -1,21 +1,21 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:splitio_platform_interface/split_fallback_treatments_configuration.dart'; +import 'package:splitio_platform_interface/split_fallback_treatments.dart'; import 'package:splitio_platform_interface/split_result.dart'; void main() { test('global and by flag fallback treatments', () { - var config = FallbackTreatmentsConfiguration(global: const SplitResult('custom-treatment', null)); + var config = FallbackTreatments(global: const SplitResult('custom-treatment', null)); expect(config.global, equals({'treatment': 'custom-treatment', 'config': null})); expect(config.byFlag, null); - config = FallbackTreatmentsConfiguration(byFlag: {'flag1': const SplitResult('custom-treatment', 'custom-config')}); + config = FallbackTreatments(byFlag: {'flag1': const SplitResult('custom-treatment', 'custom-config')}); expect(config.byFlag, equals({'flag1': {'treatment': 'custom-treatment', 'config': 'custom-config'}})); expect(config.global, null); }); test('default values', () { - var config = FallbackTreatmentsConfiguration(); + var config = FallbackTreatments(); expect(config.global, null); expect(config.byFlag, null); diff --git a/splitio_platform_interface/test/splitio_configuration_test.dart b/splitio_platform_interface/test/splitio_configuration_test.dart index 0f740d4..4c066a4 100644 --- a/splitio_platform_interface/test/splitio_configuration_test.dart +++ b/splitio_platform_interface/test/splitio_configuration_test.dart @@ -1,7 +1,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:splitio_platform_interface/split_certificate_pinning_configuration.dart'; import 'package:splitio_platform_interface/split_configuration.dart'; -import 'package:splitio_platform_interface/split_fallback_treatments_configuration.dart'; +import 'package:splitio_platform_interface/split_fallback_treatments.dart'; import 'package:splitio_platform_interface/split_result.dart'; import 'package:splitio_platform_interface/split_rollout_cache_configuration.dart'; import 'package:splitio_platform_interface/split_sync_config.dart'; @@ -39,7 +39,7 @@ void main() { .addPin('host2', 'pin3') .addPin('host1', 'pin2'), rolloutCacheConfiguration: RolloutCacheConfiguration(expirationDays: 15, clearOnInit: true), - fallbackTreatmentsConfiguration: FallbackTreatmentsConfiguration(global: const SplitResult('custom-treatment', null))); + fallbackTreatments: FallbackTreatments(global: const SplitResult('custom-treatment', null))); expect(config.configurationMap['eventFlushInterval'], 2000); expect(config.configurationMap['eventsPerPush'], 300); From 0e4853b45bf1b497e7f8c56d6e327772b4395c7a Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Mon, 19 Jan 2026 17:13:03 -0300 Subject: [PATCH 03/13] Rename FallbackTreatments to FallbackTreatmentsConfiguration --- .../lib/split_configuration.dart | 4 +-- ...it_fallback_treatments_configuration.dart} | 4 +-- ...llback_treatments_configuration_test.dart} | 8 ++--- .../test/splitio_configuration_test.dart | 34 +++++++++++++++---- 4 files changed, 35 insertions(+), 15 deletions(-) rename splitio_platform_interface/lib/{split_fallback_treatments.dart => split_fallback_treatments_configuration.dart} (88%) rename splitio_platform_interface/test/{split_fallback_treatments_test.dart => split_fallback_treatments_configuration_test.dart} (67%) diff --git a/splitio_platform_interface/lib/split_configuration.dart b/splitio_platform_interface/lib/split_configuration.dart index 28ee406..c742c48 100644 --- a/splitio_platform_interface/lib/split_configuration.dart +++ b/splitio_platform_interface/lib/split_configuration.dart @@ -1,5 +1,5 @@ import 'package:splitio_platform_interface/split_certificate_pinning_configuration.dart'; -import 'package:splitio_platform_interface/split_fallback_treatments.dart'; +import 'package:splitio_platform_interface/split_fallback_treatments_configuration.dart'; import 'package:splitio_platform_interface/split_sync_config.dart'; import 'package:splitio_platform_interface/split_rollout_cache_configuration.dart'; @@ -81,7 +81,7 @@ class SplitConfiguration { int? readyTimeout = 10, CertificatePinningConfiguration? certificatePinningConfiguration, RolloutCacheConfiguration? rolloutCacheConfiguration, - FallbackTreatments? fallbackTreatments, + FallbackTreatmentsConfiguration? fallbackTreatments, }) { if (featuresRefreshRate != null) { configurationMap['featuresRefreshRate'] = featuresRefreshRate; diff --git a/splitio_platform_interface/lib/split_fallback_treatments.dart b/splitio_platform_interface/lib/split_fallback_treatments_configuration.dart similarity index 88% rename from splitio_platform_interface/lib/split_fallback_treatments.dart rename to splitio_platform_interface/lib/split_fallback_treatments_configuration.dart index 5a46c35..53abefa 100644 --- a/splitio_platform_interface/lib/split_fallback_treatments.dart +++ b/splitio_platform_interface/lib/split_fallback_treatments_configuration.dart @@ -1,13 +1,13 @@ import 'package:splitio_platform_interface/split_result.dart'; -class FallbackTreatments { +class FallbackTreatmentsConfiguration { late Map? _global; late Map>? _byFlag; Map? get global => _global; Map>? get byFlag => _byFlag; - FallbackTreatments( + FallbackTreatmentsConfiguration( {SplitResult? global, Map? byFlag}) { _global = global != null ? {'treatment': global.treatment, 'config': global.config} diff --git a/splitio_platform_interface/test/split_fallback_treatments_test.dart b/splitio_platform_interface/test/split_fallback_treatments_configuration_test.dart similarity index 67% rename from splitio_platform_interface/test/split_fallback_treatments_test.dart rename to splitio_platform_interface/test/split_fallback_treatments_configuration_test.dart index 95914d3..b520b56 100644 --- a/splitio_platform_interface/test/split_fallback_treatments_test.dart +++ b/splitio_platform_interface/test/split_fallback_treatments_configuration_test.dart @@ -1,21 +1,21 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:splitio_platform_interface/split_fallback_treatments.dart'; +import 'package:splitio_platform_interface/split_fallback_treatments_configuration.dart'; import 'package:splitio_platform_interface/split_result.dart'; void main() { test('global and by flag fallback treatments', () { - var config = FallbackTreatments(global: const SplitResult('custom-treatment', null)); + var config = FallbackTreatmentsConfiguration(global: const SplitResult('custom-treatment', null)); expect(config.global, equals({'treatment': 'custom-treatment', 'config': null})); expect(config.byFlag, null); - config = FallbackTreatments(byFlag: {'flag1': const SplitResult('custom-treatment', 'custom-config')}); + config = FallbackTreatmentsConfiguration(byFlag: {'flag1': const SplitResult('custom-treatment', 'custom-config')}); expect(config.byFlag, equals({'flag1': {'treatment': 'custom-treatment', 'config': 'custom-config'}})); expect(config.global, null); }); test('default values', () { - var config = FallbackTreatments(); + var config = FallbackTreatmentsConfiguration(); expect(config.global, null); expect(config.byFlag, null); diff --git a/splitio_platform_interface/test/splitio_configuration_test.dart b/splitio_platform_interface/test/splitio_configuration_test.dart index 4c066a4..0534cb0 100644 --- a/splitio_platform_interface/test/splitio_configuration_test.dart +++ b/splitio_platform_interface/test/splitio_configuration_test.dart @@ -1,7 +1,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:splitio_platform_interface/split_certificate_pinning_configuration.dart'; import 'package:splitio_platform_interface/split_configuration.dart'; -import 'package:splitio_platform_interface/split_fallback_treatments.dart'; +import 'package:splitio_platform_interface/split_fallback_treatments_configuration.dart'; import 'package:splitio_platform_interface/split_result.dart'; import 'package:splitio_platform_interface/split_rollout_cache_configuration.dart'; import 'package:splitio_platform_interface/split_sync_config.dart'; @@ -38,8 +38,16 @@ void main() { .addPin('host1', 'pin1') .addPin('host2', 'pin3') .addPin('host1', 'pin2'), - rolloutCacheConfiguration: RolloutCacheConfiguration(expirationDays: 15, clearOnInit: true), - fallbackTreatments: FallbackTreatments(global: const SplitResult('custom-treatment', null))); + rolloutCacheConfiguration: + RolloutCacheConfiguration(expirationDays: 15, clearOnInit: true), + fallbackTreatments: FallbackTreatmentsConfiguration( + global: const SplitResult('custom-treatment', null), + byFlag: { + 'flag1': + const SplitResult('custom-treatment-flag1', 'config-flag1'), + 'flag2': const SplitResult('custom-treatment-flag2', null), + }, + )); expect(config.configurationMap['eventFlushInterval'], 2000); expect(config.configurationMap['eventsPerPush'], 300); @@ -76,10 +84,22 @@ void main() { 'host1': ['pin1', 'pin2'], 'host2': ['pin3'] }); - expect(config.configurationMap['rolloutCacheConfiguration']['expirationDays'], 15); - expect(config.configurationMap['rolloutCacheConfiguration']['clearOnInit'], true); - expect(config.configurationMap['fallbackTreatmentsConfiguration']['global'], equals({'treatment': 'custom-treatment', 'config': null})); - expect(config.configurationMap['fallbackTreatmentsConfiguration']['byFlag'], null); + expect( + config.configurationMap['rolloutCacheConfiguration']['expirationDays'], + 15); + expect(config.configurationMap['rolloutCacheConfiguration']['clearOnInit'], + true); + expect(config.configurationMap['fallbackTreatments']['global'], + equals({'treatment': 'custom-treatment', 'config': null})); + expect( + config.configurationMap['fallbackTreatments']['byFlag'], + equals({ + 'flag1': { + 'treatment': 'custom-treatment-flag1', + 'config': 'config-flag1' + }, + 'flag2': {'treatment': 'custom-treatment-flag2', 'config': null} + })); }); test('no special values leaves map empty', () async { From 0deae7f597ed1eccd1646cede0f3f74c17e31f0d Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 20 Jan 2026 11:48:34 -0300 Subject: [PATCH 04/13] Polishing --- .../lib/split_fallback_treatments_configuration.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/splitio_platform_interface/lib/split_fallback_treatments_configuration.dart b/splitio_platform_interface/lib/split_fallback_treatments_configuration.dart index 53abefa..3fb94e5 100644 --- a/splitio_platform_interface/lib/split_fallback_treatments_configuration.dart +++ b/splitio_platform_interface/lib/split_fallback_treatments_configuration.dart @@ -1,8 +1,8 @@ import 'package:splitio_platform_interface/split_result.dart'; class FallbackTreatmentsConfiguration { - late Map? _global; - late Map>? _byFlag; + Map? _global; + Map>? _byFlag; Map? get global => _global; Map>? get byFlag => _byFlag; From 5fc79aaaace8d53a96e1893339332a19ea9d98fa Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 20 Jan 2026 13:36:01 -0300 Subject: [PATCH 05/13] Replace SplitResult with FallbackTreatment in fallback treatments configuration --- .../lib/split_fallback_treatment.dart | 6 ++++ ...lit_fallback_treatments_configuration.dart | 4 +-- ...allback_treatments_configuration_test.dart | 28 +++++++++++++++---- .../test/splitio_configuration_test.dart | 10 +++---- 4 files changed, 35 insertions(+), 13 deletions(-) create mode 100644 splitio_platform_interface/lib/split_fallback_treatment.dart diff --git a/splitio_platform_interface/lib/split_fallback_treatment.dart b/splitio_platform_interface/lib/split_fallback_treatment.dart new file mode 100644 index 0000000..bb52ed9 --- /dev/null +++ b/splitio_platform_interface/lib/split_fallback_treatment.dart @@ -0,0 +1,6 @@ +class FallbackTreatment { + final String treatment; + final String? config; + + const FallbackTreatment(this.treatment, [this.config]); +} diff --git a/splitio_platform_interface/lib/split_fallback_treatments_configuration.dart b/splitio_platform_interface/lib/split_fallback_treatments_configuration.dart index 3fb94e5..d3c3c8d 100644 --- a/splitio_platform_interface/lib/split_fallback_treatments_configuration.dart +++ b/splitio_platform_interface/lib/split_fallback_treatments_configuration.dart @@ -1,4 +1,4 @@ -import 'package:splitio_platform_interface/split_result.dart'; +import 'package:splitio_platform_interface/split_fallback_treatment.dart'; class FallbackTreatmentsConfiguration { Map? _global; @@ -8,7 +8,7 @@ class FallbackTreatmentsConfiguration { Map>? get byFlag => _byFlag; FallbackTreatmentsConfiguration( - {SplitResult? global, Map? byFlag}) { + {FallbackTreatment? global, Map? byFlag}) { _global = global != null ? {'treatment': global.treatment, 'config': global.config} : null; diff --git a/splitio_platform_interface/test/split_fallback_treatments_configuration_test.dart b/splitio_platform_interface/test/split_fallback_treatments_configuration_test.dart index b520b56..2dd3990 100644 --- a/splitio_platform_interface/test/split_fallback_treatments_configuration_test.dart +++ b/splitio_platform_interface/test/split_fallback_treatments_configuration_test.dart @@ -1,16 +1,32 @@ import 'package:flutter_test/flutter_test.dart'; +import 'package:splitio_platform_interface/split_fallback_treatment.dart'; import 'package:splitio_platform_interface/split_fallback_treatments_configuration.dart'; -import 'package:splitio_platform_interface/split_result.dart'; void main() { test('global and by flag fallback treatments', () { - var config = FallbackTreatmentsConfiguration(global: const SplitResult('custom-treatment', null)); + var config = FallbackTreatmentsConfiguration( + global: const FallbackTreatment('custom-treatment')); - expect(config.global, equals({'treatment': 'custom-treatment', 'config': null})); + expect(config.global, + equals({'treatment': 'custom-treatment', 'config': null})); expect(config.byFlag, null); - config = FallbackTreatmentsConfiguration(byFlag: {'flag1': const SplitResult('custom-treatment', 'custom-config')}); - expect(config.byFlag, equals({'flag1': {'treatment': 'custom-treatment', 'config': 'custom-config'}})); + config = FallbackTreatmentsConfiguration(byFlag: { + 'flag1': const FallbackTreatment('custom-treatment-1', 'custom-config-1'), + 'flag2': const FallbackTreatment('custom-treatment-2', 'custom-config-2') + }); + expect( + config.byFlag, + equals({ + 'flag1': { + 'treatment': 'custom-treatment-1', + 'config': 'custom-config-1' + }, + 'flag2': { + 'treatment': 'custom-treatment-2', + 'config': 'custom-config-2' + } + })); expect(config.global, null); }); @@ -20,4 +36,4 @@ void main() { expect(config.global, null); expect(config.byFlag, null); }); -} \ No newline at end of file +} diff --git a/splitio_platform_interface/test/splitio_configuration_test.dart b/splitio_platform_interface/test/splitio_configuration_test.dart index 0534cb0..c627edb 100644 --- a/splitio_platform_interface/test/splitio_configuration_test.dart +++ b/splitio_platform_interface/test/splitio_configuration_test.dart @@ -1,8 +1,8 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:splitio_platform_interface/split_certificate_pinning_configuration.dart'; import 'package:splitio_platform_interface/split_configuration.dart'; +import 'package:splitio_platform_interface/split_fallback_treatment.dart'; import 'package:splitio_platform_interface/split_fallback_treatments_configuration.dart'; -import 'package:splitio_platform_interface/split_result.dart'; import 'package:splitio_platform_interface/split_rollout_cache_configuration.dart'; import 'package:splitio_platform_interface/split_sync_config.dart'; @@ -41,11 +41,11 @@ void main() { rolloutCacheConfiguration: RolloutCacheConfiguration(expirationDays: 15, clearOnInit: true), fallbackTreatments: FallbackTreatmentsConfiguration( - global: const SplitResult('custom-treatment', null), + global: const FallbackTreatment('custom-treatment'), byFlag: { - 'flag1': - const SplitResult('custom-treatment-flag1', 'config-flag1'), - 'flag2': const SplitResult('custom-treatment-flag2', null), + 'flag1': const FallbackTreatment( + 'custom-treatment-flag1', 'config-flag1'), + 'flag2': const FallbackTreatment('custom-treatment-flag2'), }, )); From d0a5d0417a71a0093097bed18391d5e33f35b18f Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Wed, 21 Jan 2026 12:35:22 -0300 Subject: [PATCH 06/13] Add fallbackTreatments configuration support for web platform --- splitio_web/lib/splitio_web.dart | 6 ++ splitio_web/lib/src/js_interop.dart | 7 +++ splitio_web/test/splitio_web_test.dart | 83 ++++++++++++++++---------- 3 files changed, 63 insertions(+), 33 deletions(-) diff --git a/splitio_web/lib/splitio_web.dart b/splitio_web/lib/splitio_web.dart index 6a0102f..799fe0b 100644 --- a/splitio_web/lib/splitio_web.dart +++ b/splitio_web/lib/splitio_web.dart @@ -321,6 +321,12 @@ class SplitioWeb extends SplitioPlatform { config.impressionListener = impressionListener; } + + if (configuration.configurationMap['fallbackTreatments'] != null) { + final fallbackTreatments = configuration.configurationMap['fallbackTreatments'] as Map; + // FallbackTreatmentsConfiguration has a compatible structure with JSFallbackTreatmentsConfiguration + config.fallbackTreatments = fallbackTreatments.jsify() as JSFallbackTreatmentsConfiguration; + } } return config; diff --git a/splitio_web/lib/src/js_interop.dart b/splitio_web/lib/src/js_interop.dart index df58d6e..4d5076d 100644 --- a/splitio_web/lib/src/js_interop.dart +++ b/splitio_web/lib/src/js_interop.dart @@ -90,6 +90,12 @@ extension type JSConfigurationStorage._(JSObject _) implements JSObject { external JSBoolean? clearOnInit; } +@JS() +extension type JSFallbackTreatmentsConfiguration._(JSObject _) implements JSObject { + external JSTreatmentWithConfig? global; + external JSObject? byFlag; +} + @JS() extension type JSConfiguration._(JSObject _) implements JSObject { external JSConfigurationCore core; @@ -102,6 +108,7 @@ extension type JSConfiguration._(JSObject _) implements JSObject { external JSImpressionListener? impressionListener; external JSAny? debug; external JSAny? storage; + external JSFallbackTreatmentsConfiguration? fallbackTreatments; } @JS() diff --git a/splitio_web/test/splitio_web_test.dart b/splitio_web/test/splitio_web_test.dart index 13c386e..44151c7 100644 --- a/splitio_web/test/splitio_web_test.dart +++ b/splitio_web/test/splitio_web_test.dart @@ -7,6 +7,8 @@ import 'package:splitio_web/src/js_interop.dart'; import 'package:splitio_platform_interface/split_certificate_pinning_configuration.dart'; import 'package:splitio_platform_interface/split_sync_config.dart'; import 'package:splitio_platform_interface/split_rollout_cache_configuration.dart'; +import 'package:splitio_platform_interface/split_fallback_treatment.dart'; +import 'package:splitio_platform_interface/split_fallback_treatments_configuration.dart'; import 'utils/js_interop_test_utils.dart'; extension on web.Window { @@ -685,39 +687,47 @@ void main() { 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', - // ignore: deprecated_member_use - enableDebug: false, // deprecated, logLevel has precedence - streamingEnabled: false, - persistentAttributesEnabled: true, // unsupported in Web - impressionListener: true, - sdkEndpoint: 'https://sdk.domain/api', - eventsEndpoint: 'https://events.domain/api', - authServiceEndpoint: 'https://auth.domain/api/v2', - streamingServiceEndpoint: 'https://streaming.domain/sse', - telemetryServiceEndpoint: 'https://telemetry.domain/api/v1', - 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() - .addPin('host', 'pin'), // unsupported in Web - rolloutCacheConfiguration: RolloutCacheConfiguration( - expirationDays: 100, - clearOnInit: true, - ))); + featuresRefreshRate: 1, + segmentsRefreshRate: 2, + impressionsRefreshRate: 3, + telemetryRefreshRate: 4, + eventsQueueSize: 5, + impressionsQueueSize: 6, + eventFlushInterval: 7, + eventsPerPush: 8, // unsupported in Web + trafficType: 'user', + // ignore: deprecated_member_use + enableDebug: false, // deprecated, logLevel has precedence + streamingEnabled: false, + persistentAttributesEnabled: true, // unsupported in Web + impressionListener: true, + sdkEndpoint: 'https://sdk.domain/api', + eventsEndpoint: 'https://events.domain/api', + authServiceEndpoint: 'https://auth.domain/api/v2', + streamingServiceEndpoint: 'https://streaming.domain/sse', + telemetryServiceEndpoint: 'https://telemetry.domain/api/v1', + 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() + .addPin('host', 'pin'), // unsupported in Web + rolloutCacheConfiguration: RolloutCacheConfiguration( + expirationDays: 100, + clearOnInit: true, + ), + fallbackTreatments: FallbackTreatmentsConfiguration( + global: const FallbackTreatment('global-treatment'), + byFlag: { + 'flag_1': const FallbackTreatment('fallback_1', 'config_1'), + 'flag_2': const FallbackTreatment('fallback_2', null) + }, + ), + )); expect(mock.calls[mock.calls.length - 5].methodName, 'SplitFactory'); final actual = @@ -776,6 +786,13 @@ void main() { 'impressionListener': { 'logImpression': (actual as Map)['impressionListener'] ['logImpression'] + }, + 'fallbackTreatments': { + 'global': {'treatment': 'global-treatment', 'config': null}, + 'byFlag': { + 'flag_1': {'treatment': 'fallback_1', 'config': 'config_1'}, + 'flag_2': {'treatment': 'fallback_2', 'config': null} + } } })); From 3b0327bf66ae1679293bd757d693d36d4468afa9 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 27 Jan 2026 15:58:57 -0300 Subject: [PATCH 07/13] Add fallback treatments configuration support for Android and iOS platforms --- splitio/lib/splitio.dart | 2 ++ splitio_android/android/build.gradle | 2 +- .../splitio/SplitClientConfigHelper.java | 30 ++++++++++++++++++ .../splitio/SplitClientConfigHelperTest.java | 31 +++++++++++++++++++ splitio_ios/example/ios/Podfile.lock | 14 ++++----- .../SplitClientConfigHelperTests.swift | 25 +++++++++++++++ .../ios/Classes/SplitClientConfigHelper.swift | 29 +++++++++++++++++ splitio_ios/ios/splitio_ios.podspec | 4 +-- 8 files changed, 127 insertions(+), 10 deletions(-) diff --git a/splitio/lib/splitio.dart b/splitio/lib/splitio.dart index a037b11..27cd8fe 100644 --- a/splitio/lib/splitio.dart +++ b/splitio/lib/splitio.dart @@ -12,6 +12,8 @@ export 'package:splitio_platform_interface/split_view.dart'; export 'package:splitio_platform_interface/split_certificate_pinning_configuration.dart'; export 'package:splitio_platform_interface/split_evaluation_options.dart'; export 'package:splitio_platform_interface/split_rollout_cache_configuration.dart'; +export 'package:splitio_platform_interface/split_fallback_treatment.dart'; +export 'package:splitio_platform_interface/split_fallback_treatments_configuration.dart'; typedef ClientReadinessCallback = void Function(SplitClient splitClient); diff --git a/splitio_android/android/build.gradle b/splitio_android/android/build.gradle index 0cd5200..18edceb 100644 --- a/splitio_android/android/build.gradle +++ b/splitio_android/android/build.gradle @@ -38,7 +38,7 @@ android { } dependencies { - implementation 'io.split.client:android-client:5.3.1' + implementation 'io.split.client:android-client:5.4.1' testImplementation 'junit:junit:4.13.2' testImplementation 'org.mockito:mockito-core:3.12.4' diff --git a/splitio_android/android/src/main/java/io/split/splitio/SplitClientConfigHelper.java b/splitio_android/android/src/main/java/io/split/splitio/SplitClientConfigHelper.java index 2df8e0d..da35b35 100644 --- a/splitio_android/android/src/main/java/io/split/splitio/SplitClientConfigHelper.java +++ b/splitio_android/android/src/main/java/io/split/splitio/SplitClientConfigHelper.java @@ -19,6 +19,8 @@ import io.split.android.client.network.CertificatePinningConfiguration; import io.split.android.client.shared.UserConsent; import io.split.android.client.utils.logger.SplitLogLevel; +import io.split.android.client.fallback.FallbackTreatmentsConfiguration; +import io.split.android.client.fallback.FallbackTreatment; class SplitClientConfigHelper { @@ -55,6 +57,11 @@ class SplitClientConfigHelper { private static final String ROLLOUT_CACHE_CONFIGURATION = "rolloutCacheConfiguration"; private static final String ROLLOUT_CACHE_CONFIGURATION_EXPIRATION = "expirationDays"; private static final String ROLLOUT_CACHE_CONFIGURATION_CLEAR_ON_INIT = "clearOnInit"; + private static final String FALLBACK_TREATMENTS = "fallbackTreatments"; + private static final String FALLBACK_TREATMENTS_GLOBAL = "global"; + private static final String FALLBACK_TREATMENTS_BY_FLAG = "byFlag"; + private static final String FALLBACK_TREATMENT_VALUE = "treatment"; + private static final String FALLBACK_TREATMENT_CONFIG = "config"; /** * Creates a {@link SplitClientConfig} object from a map. @@ -262,6 +269,29 @@ static SplitClientConfig fromMap(@NonNull Map configurationMap, } } + Map fallbackTreatments = getObjectMap(configurationMap, FALLBACK_TREATMENTS); + if (fallbackTreatments != null) { + Map global = getObjectMap(fallbackTreatments, FALLBACK_TREATMENTS_GLOBAL); + Map byFlag = getObjectMap(fallbackTreatments, FALLBACK_TREATMENTS_BY_FLAG); + if (global != null || byFlag != null) { + FallbackTreatmentsConfiguration.Builder fallbackTreatmentsBuilder = FallbackTreatmentsConfiguration.builder(); + if (global != null) { + fallbackTreatmentsBuilder.global(new FallbackTreatment(getString(global, FALLBACK_TREATMENT_VALUE), getString(global, FALLBACK_TREATMENT_CONFIG))); + } + if (byFlag != null) { + Map byFlagMap = new HashMap<>(); + for (Map.Entry entry : byFlag.entrySet()) { + Map byFlagFallbackTreatment = getObjectMap(byFlag, entry.getKey()); + if (byFlagFallbackTreatment != null) { + byFlagMap.put(entry.getKey(), new FallbackTreatment(getString(byFlagFallbackTreatment, FALLBACK_TREATMENT_VALUE), getString(byFlagFallbackTreatment, FALLBACK_TREATMENT_CONFIG))); + } + } + fallbackTreatmentsBuilder.byFlag(byFlagMap); + } + builder.fallbackTreatments(fallbackTreatmentsBuilder.build()); + } + } + return builder.serviceEndpoints(serviceEndpointsBuilder.build()).build(); } diff --git a/splitio_android/android/src/test/java/io/split/splitio/SplitClientConfigHelperTest.java b/splitio_android/android/src/test/java/io/split/splitio/SplitClientConfigHelperTest.java index 23a5215..ebd20f6 100644 --- a/splitio_android/android/src/test/java/io/split/splitio/SplitClientConfigHelperTest.java +++ b/splitio_android/android/src/test/java/io/split/splitio/SplitClientConfigHelperTest.java @@ -27,6 +27,8 @@ import io.split.android.client.utils.logger.LogPrinter; import io.split.android.client.utils.logger.Logger; import io.split.android.client.utils.logger.SplitLogLevel; +import io.split.android.client.fallback.FallbackTreatmentsConfiguration; +import io.split.android.client.fallback.FallbackTreatment; public class SplitClientConfigHelperTest { @@ -235,4 +237,33 @@ public void rolloutCacheConfigurationValuesAreMappedCorrectly() { assertEquals(5, splitClientConfig.rolloutCacheConfiguration().getExpirationDays()); assertTrue(splitClientConfig.rolloutCacheConfiguration().isClearOnInit()); } + + @Test + public void fallbackTreatmentsValuesAreMappedCorrectly() { + Map globalFallbackTreatment = new HashMap<>(); + globalFallbackTreatment.put("treatment", "global-control"); + globalFallbackTreatment.put("config", "global-config"); + + Map feature1FallbackTreatment = new HashMap<>(); + feature1FallbackTreatment.put("treatment", "feature1-control"); + feature1FallbackTreatment.put("config", null); + + Map byFlagFallbackTreatments = new HashMap<>(); + byFlagFallbackTreatments.put("feature1", feature1FallbackTreatment); + + Map fallbackTreatmentsValues = new HashMap<>(); + fallbackTreatmentsValues.put("global", globalFallbackTreatment); + fallbackTreatmentsValues.put("byFlag", byFlagFallbackTreatments); + + Map configValues = new HashMap<>(); + configValues.put("fallbackTreatments", fallbackTreatmentsValues); + + SplitClientConfig splitClientConfig = SplitClientConfigHelper + .fromMap(configValues, mock(ImpressionListener.class)); + + FallbackTreatmentsConfiguration fallbackTreatmentsConfiguration = splitClientConfig.fallbackTreatments(); + + assertEquals(new FallbackTreatment("global-control", "global-config"), fallbackTreatmentsConfiguration.getGlobal()); + assertEquals(Map.of("feature1", new FallbackTreatment("feature1-control", null)), fallbackTreatmentsConfiguration.getByFlag()); + } } diff --git a/splitio_ios/example/ios/Podfile.lock b/splitio_ios/example/ios/Podfile.lock index ea8a88c..5b23eda 100644 --- a/splitio_ios/example/ios/Podfile.lock +++ b/splitio_ios/example/ios/Podfile.lock @@ -1,9 +1,9 @@ PODS: - Flutter (1.0.0) - - Split (3.3.2) - - splitio_ios (0.8.0): + - Split (3.6.0) + - splitio_ios (0.9.0): - Flutter - - Split (~> 3.3.2) + - Split (~> 3.6.0) DEPENDENCIES: - Flutter (from `Flutter`) @@ -20,10 +20,10 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/splitio_ios/ios" SPEC CHECKSUMS: - Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 - Split: 0d4962a6c15180e1857c1a3753e1ae9c91a6150b - splitio_ios: 438ad21d0dfe467670f8b9508773b77b16a71d6b + Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 + Split: 1e2176aacd6421029bea41413401389d86e3d50a + splitio_ios: ad4f484a6c478bf7285e417ea8252371f66b54ff -PODFILE CHECKSUM: aed42fc5c94ade572556b7ed357c5c57f1bd83a2 +PODFILE CHECKSUM: ba5baa820782b9e142d3ba97a6b84de9feaaceda COCOAPODS: 1.16.2 diff --git a/splitio_ios/example/ios/SplitTests/SplitClientConfigHelperTests.swift b/splitio_ios/example/ios/SplitTests/SplitClientConfigHelperTests.swift index 2c29a06..8475535 100644 --- a/splitio_ios/example/ios/SplitTests/SplitClientConfigHelperTests.swift +++ b/splitio_ios/example/ios/SplitTests/SplitClientConfigHelperTests.swift @@ -154,4 +154,29 @@ class SplitClientConfigHelperTests: XCTestCase { XCTAssertEqual(5, actualConfig.expirationDays) XCTAssertTrue(actualConfig.clearOnInit) } + + func testFallbackTreatmentsConfigurationValuesAreMappedCorrectly() { + let configValues = [ + "fallbackTreatments": [ + "global": [ + "treatment": "on", + "config": "{\"key\": \"value\"}" + ], + "byFlag": [ + "feature1": [ + "treatment": "off", + "config": nil + ] + ] + ] + ] + + let splitClientConfig: SplitClientConfig = SplitClientConfigHelper.fromMap(configurationMap: configValues, impressionListener: nil) + let actualConfig = splitClientConfig.fallbackTreatments + + XCTAssertEqual("on", actualConfig.global?.treatment) + XCTAssertEqual("{\"key\": \"value\"}", actualConfig.global?.config) + XCTAssertEqual("off", actualConfig.byFlag["feature1"]?.treatment) + XCTAssertNil(actualConfig.byFlag["feature1"]?.config) + } } diff --git a/splitio_ios/ios/Classes/SplitClientConfigHelper.swift b/splitio_ios/ios/Classes/SplitClientConfigHelper.swift index abe76d0..63c8d22 100644 --- a/splitio_ios/ios/Classes/SplitClientConfigHelper.swift +++ b/splitio_ios/ios/Classes/SplitClientConfigHelper.swift @@ -36,6 +36,11 @@ class SplitClientConfigHelper { static private let ROLLOUT_CACHE_CONFIGURATION = "rolloutCacheConfiguration" static private let ROLLOUT_CACHE_CONFIGURATION_EXPIRATION = "expirationDays" static private let ROLLOUT_CACHE_CONFIGURATION_CLEAR_ON_INIT = "clearOnInit" + static private let FALLBACK_TREATMENTS = "fallbackTreatments"; + static private let FALLBACK_TREATMENTS_GLOBAL = "global"; + static private let FALLBACK_TREATMENTS_BY_FLAG = "byFlag"; + static private let FALLBACK_TREATMENT_VALUE = "treatment"; + static private let FALLBACK_TREATMENT_CONFIG = "config"; static func fromMap(configurationMap: [String: Any?], impressionListener: SplitImpressionListener?) -> SplitClientConfig { let config = SplitClientConfig() @@ -253,6 +258,30 @@ class SplitClientConfigHelper { config.rolloutCacheConfiguration = rolloutCacheConfigurationBuilder.build() } + if let fallbackTreatmentConfig = configurationMap[FALLBACK_TREATMENTS] as? [String: Any?] { + let fallbackTreatmentConfiguration = FallbackTreatmentsConfig.builder() + + if let globalTreatment = fallbackTreatmentConfig[FALLBACK_TREATMENTS_GLOBAL] as? [String: Any?] { + fallbackTreatmentConfiguration.global(FallbackTreatment( + treatment: globalTreatment[FALLBACK_TREATMENT_VALUE] as! String, + config: globalTreatment[FALLBACK_TREATMENT_CONFIG] as? String + )) + } + + if let byFlagTreatments = fallbackTreatmentConfig[FALLBACK_TREATMENTS_BY_FLAG] as? [String: [String: Any?]] { + var byFlag: [String: FallbackTreatment] = [:] + for (key, value) in byFlagTreatments { + byFlag[key] = FallbackTreatment( + treatment: value[FALLBACK_TREATMENT_VALUE] as! String, + config: value[FALLBACK_TREATMENT_CONFIG] as? String + ) + } + fallbackTreatmentConfiguration.byFlag(byFlag) + } + + config.fallbackTreatments = fallbackTreatmentConfiguration.build() + } + return config } diff --git a/splitio_ios/ios/splitio_ios.podspec b/splitio_ios/ios/splitio_ios.podspec index bb24308..cdbf4e7 100644 --- a/splitio_ios/ios/splitio_ios.podspec +++ b/splitio_ios/ios/splitio_ios.podspec @@ -4,7 +4,7 @@ # Pod::Spec.new do |s| s.name = 'splitio_ios' - s.version = '0.8.0' + s.version = '0.9.0' s.summary = 'split.io official Flutter plugin.' s.description = <<-DESC split.io official Flutter plugin. @@ -15,7 +15,7 @@ split.io official Flutter plugin. s.source = { :path => '.' } s.source_files = 'Classes/**/*' s.dependency 'Flutter' - s.dependency 'Split', '~> 3.3.2' + s.dependency 'Split', '~> 3.6.0' s.platform = :ios, '9.0' # Flutter.framework does not contain a i386 slice. From e0df25f917feb38efab25e999b85b67120c33be2 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 27 Jan 2026 16:12:19 -0300 Subject: [PATCH 08/13] Update example podfile --- splitio/example/ios/Podfile.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/splitio/example/ios/Podfile.lock b/splitio/example/ios/Podfile.lock index e004592..c23d777 100644 --- a/splitio/example/ios/Podfile.lock +++ b/splitio/example/ios/Podfile.lock @@ -1,9 +1,9 @@ PODS: - Flutter (1.0.0) - - Split (3.3.2) - - splitio_ios (0.8.0): + - Split (3.6.0) + - splitio_ios (0.9.0): - Flutter - - Split (~> 3.3.2) + - Split (~> 3.6.0) DEPENDENCIES: - Flutter (from `Flutter`) @@ -20,9 +20,9 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/splitio_ios/ios" SPEC CHECKSUMS: - Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 - Split: 0d4962a6c15180e1857c1a3753e1ae9c91a6150b - splitio_ios: 438ad21d0dfe467670f8b9508773b77b16a71d6b + Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 + Split: 1e2176aacd6421029bea41413401389d86e3d50a + splitio_ios: ad4f484a6c478bf7285e417ea8252371f66b54ff PODFILE CHECKSUM: 4e8f8b2be68aeea4c0d5beb6ff1e79fface1d048 From c126f94dcbbaedda759111708a187d7a9d6cd168 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 27 Jan 2026 16:27:05 -0300 Subject: [PATCH 09/13] Switch dependencies to local path references for development --- splitio/pubspec.yaml | 12 ++++++++---- splitio_android/pubspec.yaml | 3 ++- splitio_ios/pubspec.yaml | 3 ++- splitio_web/pubspec.yaml | 3 ++- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/splitio/pubspec.yaml b/splitio/pubspec.yaml index a762f9f..79e7a0a 100644 --- a/splitio/pubspec.yaml +++ b/splitio/pubspec.yaml @@ -21,10 +21,14 @@ flutter: dependencies: flutter: sdk: flutter - splitio_android: ^1.0.0 - splitio_ios: ^1.0.0 - splitio_web: ^1.0.0 - splitio_platform_interface: ^2.0.0 + splitio_android: # ^1.0.0 + path: ../splitio_android + splitio_ios: # ^1.0.0 + path: ../splitio_ios + splitio_web: # ^1.0.0 + path: ../splitio_web + splitio_platform_interface: # ^2.0.0 + path: ../splitio_platform_interface dev_dependencies: flutter_test: sdk: flutter diff --git a/splitio_android/pubspec.yaml b/splitio_android/pubspec.yaml index fc2bbbe..6935678 100644 --- a/splitio_android/pubspec.yaml +++ b/splitio_android/pubspec.yaml @@ -19,7 +19,8 @@ flutter: dependencies: flutter: sdk: flutter - splitio_platform_interface: ^2.0.0 + splitio_platform_interface: # ^2.0.0 + path: ../splitio_platform_interface dev_dependencies: flutter_test: diff --git a/splitio_ios/pubspec.yaml b/splitio_ios/pubspec.yaml index 8c6637b..1d4c6cf 100644 --- a/splitio_ios/pubspec.yaml +++ b/splitio_ios/pubspec.yaml @@ -18,7 +18,8 @@ flutter: dependencies: flutter: sdk: flutter - splitio_platform_interface: ^2.0.0 + splitio_platform_interface: # ^2.0.0 + path: ../splitio_platform_interface dev_dependencies: flutter_test: diff --git a/splitio_web/pubspec.yaml b/splitio_web/pubspec.yaml index 72e04bb..ae86de9 100644 --- a/splitio_web/pubspec.yaml +++ b/splitio_web/pubspec.yaml @@ -20,7 +20,8 @@ flutter: dependencies: flutter: sdk: flutter - splitio_platform_interface: ^2.0.0 + splitio_platform_interface: # ^2.0.0 + path: ../splitio_platform_interface flutter_web_plugins: sdk: flutter web: ">=0.5.0 <2.0.0" From 0898585248b52168f2ab861ef2c4cf1952f4ae80 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Wed, 28 Jan 2026 10:52:05 -0300 Subject: [PATCH 10/13] Update splitio_android/android/build.gradle Co-authored-by: gthea --- splitio_android/android/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/splitio_android/android/build.gradle b/splitio_android/android/build.gradle index 18edceb..723d466 100644 --- a/splitio_android/android/build.gradle +++ b/splitio_android/android/build.gradle @@ -38,7 +38,7 @@ android { } dependencies { - implementation 'io.split.client:android-client:5.4.1' + implementation 'io.split.client:android-client:5.4.2' testImplementation 'junit:junit:4.13.2' testImplementation 'org.mockito:mockito-core:3.12.4' From be61d4c7ff950bae0caeedb659e1f6e04a4cd476 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Wed, 28 Jan 2026 14:05:05 -0300 Subject: [PATCH 11/13] prepare release --- splitio/CHANGELOG.md | 2 ++ splitio/pubspec.yaml | 14 +++++--------- splitio_android/CHANGELOG.md | 2 ++ splitio_android/pubspec.yaml | 5 ++--- splitio_ios/CHANGELOG.md | 2 ++ splitio_ios/pubspec.yaml | 5 ++--- splitio_platform_interface/CHANGELOG.md | 2 ++ splitio_platform_interface/pubspec.yaml | 2 +- splitio_web/CHANGELOG.md | 7 +++---- splitio_web/pubspec.yaml | 5 ++--- 10 files changed, 23 insertions(+), 23 deletions(-) diff --git a/splitio/CHANGELOG.md b/splitio/CHANGELOG.md index 5fe4e9a..01e41b7 100644 --- a/splitio/CHANGELOG.md +++ b/splitio/CHANGELOG.md @@ -1,3 +1,5 @@ +# 1.2.0-rc.1 (Jan 28, 2026) + # 1.1.0 (Jan 16, 2026) - Added Web support via the `splitio_web` package, the Web implementation of `splitio` based on the Split Browser SDK `1.6.0`. diff --git a/splitio/pubspec.yaml b/splitio/pubspec.yaml index 79e7a0a..3166761 100644 --- a/splitio/pubspec.yaml +++ b/splitio/pubspec.yaml @@ -1,6 +1,6 @@ name: splitio description: Official plugin for split.io, the platform for controlled rollouts, which serves features to your users via feature flags to manage your complete customer experience. -version: 1.1.0 +version: 1.2.0-rc.1 homepage: https://split.io/ repository: https://github.com/splitio/flutter-sdk-plugin/tree/main/splitio/ @@ -21,14 +21,10 @@ flutter: dependencies: flutter: sdk: flutter - splitio_android: # ^1.0.0 - path: ../splitio_android - splitio_ios: # ^1.0.0 - path: ../splitio_ios - splitio_web: # ^1.0.0 - path: ../splitio_web - splitio_platform_interface: # ^2.0.0 - path: ../splitio_platform_interface + splitio_android: ^1.1.0-rc.1 + splitio_ios: ^1.1.0-rc.1 + splitio_web: ^1.1.0-rc.1 + splitio_platform_interface: ^2.1.0-rc.1 dev_dependencies: flutter_test: sdk: flutter diff --git a/splitio_android/CHANGELOG.md b/splitio_android/CHANGELOG.md index 6f47087..a6a85b8 100644 --- a/splitio_android/CHANGELOG.md +++ b/splitio_android/CHANGELOG.md @@ -1,3 +1,5 @@ +# 1.1.0-rc.1 (Jan 28, 2026) + # 1.0.0 (Aug 14, 2025) - Updated Android SDK to `5.3.1`. diff --git a/splitio_android/pubspec.yaml b/splitio_android/pubspec.yaml index 6935678..463872b 100644 --- a/splitio_android/pubspec.yaml +++ b/splitio_android/pubspec.yaml @@ -1,7 +1,7 @@ name: splitio_android description: The official Android implementation of splitio Flutter plugin. repository: https://github.com/splitio/flutter-sdk-plugin/tree/main/splitio_android -version: 1.0.0 +version: 1.1.0-rc.1 environment: sdk: ">=2.16.2 <4.0.0" @@ -19,8 +19,7 @@ flutter: dependencies: flutter: sdk: flutter - splitio_platform_interface: # ^2.0.0 - path: ../splitio_platform_interface + splitio_platform_interface: ^2.1.0-rc.1 dev_dependencies: flutter_test: diff --git a/splitio_ios/CHANGELOG.md b/splitio_ios/CHANGELOG.md index d0935b9..f72181d 100644 --- a/splitio_ios/CHANGELOG.md +++ b/splitio_ios/CHANGELOG.md @@ -1,3 +1,5 @@ +# 1.1.0-rc.1 (Jan 28, 2026) + # 1.0.0 (Aug 14, 2025) - iOS SDK to `3.3.2` diff --git a/splitio_ios/pubspec.yaml b/splitio_ios/pubspec.yaml index 1d4c6cf..e986ac0 100644 --- a/splitio_ios/pubspec.yaml +++ b/splitio_ios/pubspec.yaml @@ -1,7 +1,7 @@ name: splitio_ios description: The official iOS implementation of splitio Flutter plugin. repository: https://github.com/splitio/flutter-sdk-plugin/tree/main/splitio_ios -version: 1.0.0 +version: 1.1.0-rc.1 environment: sdk: ">=2.16.2 <4.0.0" @@ -18,8 +18,7 @@ flutter: dependencies: flutter: sdk: flutter - splitio_platform_interface: # ^2.0.0 - path: ../splitio_platform_interface + splitio_platform_interface: ^2.1.0-rc.1 dev_dependencies: flutter_test: diff --git a/splitio_platform_interface/CHANGELOG.md b/splitio_platform_interface/CHANGELOG.md index cf67b5e..9402aa4 100644 --- a/splitio_platform_interface/CHANGELOG.md +++ b/splitio_platform_interface/CHANGELOG.md @@ -1,3 +1,5 @@ +# 2.1.0-rc.1 (Jan 28, 2026) + # 2.0.0 (Aug 14, 2025) # 2.0.0-rc.1 (Aug 14, 2025) diff --git a/splitio_platform_interface/pubspec.yaml b/splitio_platform_interface/pubspec.yaml index 6b2a0e1..5273aa5 100644 --- a/splitio_platform_interface/pubspec.yaml +++ b/splitio_platform_interface/pubspec.yaml @@ -2,7 +2,7 @@ name: splitio_platform_interface description: A common platform interface for the splitio plugin. # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.0.0 +version: 2.1.0-rc.1 repository: https://github.com/splitio/flutter-sdk-plugin/tree/main/splitio_platform_interface environment: diff --git a/splitio_web/CHANGELOG.md b/splitio_web/CHANGELOG.md index ccade9c..f9989b9 100644 --- a/splitio_web/CHANGELOG.md +++ b/splitio_web/CHANGELOG.md @@ -1,7 +1,6 @@ -# 1.0.1 (January XX, 2026) -- Updated Browser SDK to `1.6.1`. +# 1.1.0-rc.1 (Jan 28, 2026) -# 1.0.0 (January 16, 2026) +# 1.0.0 (Jan 16, 2026) - Initial release. Web implementation of `splitio` based on Split Browser SDK `1.6.0`. -# 1.0.0-rc.1 (January 15, 2026) +# 1.0.0-rc.1 (Jan 15, 2026) diff --git a/splitio_web/pubspec.yaml b/splitio_web/pubspec.yaml index ae86de9..7294cb4 100644 --- a/splitio_web/pubspec.yaml +++ b/splitio_web/pubspec.yaml @@ -1,7 +1,7 @@ name: splitio_web description: The official Web implementation of splitio Flutter plugin. repository: https://github.com/splitio/flutter-sdk-plugin/tree/main/splitio_web -version: 1.0.0 +version: 1.1.0-rc.1 environment: sdk: ">=3.3.0 <4.0.0" # using Dart 3.3+ extension types for JS interop @@ -20,8 +20,7 @@ flutter: dependencies: flutter: sdk: flutter - splitio_platform_interface: # ^2.0.0 - path: ../splitio_platform_interface + splitio_platform_interface: ^2.1.0-rc.1 flutter_web_plugins: sdk: flutter web: ">=0.5.0 <2.0.0" From 408ccb8807df58d3069e87f8576cc379962f4aeb Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Wed, 28 Jan 2026 16:40:56 -0300 Subject: [PATCH 12/13] add public_member_api_docs rule --- splitio/analysis_options.yaml | 4 + splitio/example/lib/main.dart | 2 + splitio/lib/split_client.dart | 3 + splitio/lib/splitio.dart | 12 ++ splitio_android/analysis_options.yaml | 4 + splitio_ios/analysis_options.yaml | 4 + .../analysis_options.yaml | 4 + .../lib/events/split_method_call_handler.dart | 8 ++ .../impressions_method_call_handler.dart | 1 + .../lib/method_call_handler.dart | 4 + .../lib/method_channel_platform.dart | 4 + ...lit_certificate_pinning_configuration.dart | 6 +- .../lib/split_configuration.dart | 37 +++++- .../lib/split_evaluation_options.dart | 5 + .../lib/split_fallback_treatment.dart | 5 + ...lit_fallback_treatments_configuration.dart | 5 + .../lib/split_impression.dart | 20 ++++ .../lib/split_prerequisite.dart | 6 + .../lib/split_result.dart | 4 + .../split_rollout_cache_configuration.dart | 9 +- .../lib/split_sync_config.dart | 7 ++ .../lib/split_view.dart | 22 ++++ .../lib/splitio_platform_interface.dart | 2 + splitio_web/analysis_options.yaml | 4 + splitio_web/lib/src/js_interop.dart | 108 +++++++++++++++++- 25 files changed, 284 insertions(+), 6 deletions(-) diff --git a/splitio/analysis_options.yaml b/splitio/analysis_options.yaml index a5744c1..5cf0db1 100644 --- a/splitio/analysis_options.yaml +++ b/splitio/analysis_options.yaml @@ -2,3 +2,7 @@ include: package:flutter_lints/flutter.yaml # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options + +linter: + rules: + - public_member_api_docs diff --git a/splitio/example/lib/main.dart b/splitio/example/lib/main.dart index 998a90b..a27a0a5 100644 --- a/splitio/example/lib/main.dart +++ b/splitio/example/lib/main.dart @@ -1,3 +1,5 @@ +// ignore_for_file: avoid_print + import 'package:flutter/material.dart'; import 'package:splitio/splitio.dart'; diff --git a/splitio/lib/split_client.dart b/splitio/lib/split_client.dart index 883a9f4..cfa2c00 100644 --- a/splitio/lib/split_client.dart +++ b/splitio/lib/split_client.dart @@ -1,5 +1,6 @@ import 'package:splitio_platform_interface/splitio_platform_interface.dart'; +/// Abstract class representing a Split client. abstract class SplitClient { /// Performs an evaluation for the [featureFlagName] feature flag. /// @@ -187,11 +188,13 @@ abstract class SplitClient { Future whenTimeout(); } +/// Default implementation of the Split client. class DefaultSplitClient implements SplitClient { final SplitioPlatform _platform; final String _matchingKey; final String? _bucketingKey; + /// Creates a new instance of the Split client. DefaultSplitClient(this._platform, this._matchingKey, this._bucketingKey); @override diff --git a/splitio/lib/splitio.dart b/splitio/lib/splitio.dart index 27cd8fe..ae56ab1 100644 --- a/splitio/lib/splitio.dart +++ b/splitio/lib/splitio.dart @@ -15,8 +15,10 @@ export 'package:splitio_platform_interface/split_rollout_cache_configuration.dar export 'package:splitio_platform_interface/split_fallback_treatment.dart'; export 'package:splitio_platform_interface/split_fallback_treatments_configuration.dart'; +/// Callback function type for client readiness events. typedef ClientReadinessCallback = void Function(SplitClient splitClient); +/// Main class for interacting with the Split Flutter SDK. class Splitio { final String _sdkKey; @@ -114,12 +116,14 @@ class Splitio { return client; } + /// Gets the list of all feature flag names. Future> splitNames() async { List splitNames = await _platform.splitNames(); return splitNames; } + /// Gets the list of all feature flag views. Future> splits() async { return _platform.splits(); } @@ -130,14 +134,22 @@ class Splitio { return _platform.impressionsStream(); } + /// Gets a specific feature flag view. + /// + /// Returns null if the provided feature flag name is not found. Future split(String splitName) async { return _platform.split(splitName: splitName); } + /// Gets the user consent status. Future getUserConsent() async { return _platform.getUserConsent(); } + /// Sets the user consent status. + /// + /// [enabled] is a boolean that enables (`UserConsent.granted`) + /// or disables (`UserConsent.declined`) data collection. Future setUserConsent(bool enabled) async { return _platform.setUserConsent(enabled); } diff --git a/splitio_android/analysis_options.yaml b/splitio_android/analysis_options.yaml index a5744c1..5cf0db1 100644 --- a/splitio_android/analysis_options.yaml +++ b/splitio_android/analysis_options.yaml @@ -2,3 +2,7 @@ include: package:flutter_lints/flutter.yaml # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options + +linter: + rules: + - public_member_api_docs diff --git a/splitio_ios/analysis_options.yaml b/splitio_ios/analysis_options.yaml index a5744c1..5cf0db1 100644 --- a/splitio_ios/analysis_options.yaml +++ b/splitio_ios/analysis_options.yaml @@ -2,3 +2,7 @@ include: package:flutter_lints/flutter.yaml # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options + +linter: + rules: + - public_member_api_docs diff --git a/splitio_platform_interface/analysis_options.yaml b/splitio_platform_interface/analysis_options.yaml index a5744c1..5cf0db1 100644 --- a/splitio_platform_interface/analysis_options.yaml +++ b/splitio_platform_interface/analysis_options.yaml @@ -2,3 +2,7 @@ include: package:flutter_lints/flutter.yaml # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options + +linter: + rules: + - public_member_api_docs diff --git a/splitio_platform_interface/lib/events/split_method_call_handler.dart b/splitio_platform_interface/lib/events/split_method_call_handler.dart index 6a0db02..4c58431 100644 --- a/splitio_platform_interface/lib/events/split_method_call_handler.dart +++ b/splitio_platform_interface/lib/events/split_method_call_handler.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:splitio_platform_interface/method_call_handler.dart'; +/// Handler for Split SDK events class SplitEventMethodCallHandler implements MethodCallHandler { static const String _eventClientReady = 'clientReady'; static const String _eventClientReadyFromCache = 'clientReadyFromCache'; @@ -24,6 +25,7 @@ class SplitEventMethodCallHandler implements MethodCallHandler { _eventClientTimeout: false, }; + /// Creates a new instance of the Split event method call handler. SplitEventMethodCallHandler(this._matchingKey, this._bucketingKey); @override @@ -48,26 +50,32 @@ class SplitEventMethodCallHandler implements MethodCallHandler { } } + /// Returns Future that is completed when the SDK client is ready. Future onReady() { return _onEvent(_eventClientReady); } + /// Returns Future that is completed when the SDK client is ready from cache. Future onReadyFromCache() { return _onEvent(_eventClientReadyFromCache); } + /// Returns Stream that emits when the SDK client is updated. Stream onUpdated() { return _updateStreamCompleter.stream; } + /// Returns Future that is completed when the SDK client times out. Future onTimeout() { return _onEvent(_eventClientTimeout); } + /// Cleans up resources. void destroy() { _updateStreamCompleter.close(); } + /// Returns Future that is completed when the specified SDK event occurs. Future _onEvent(String sdkEvent) { if (_triggeredClientEvents.containsKey(sdkEvent) && _triggeredClientEvents[sdkEvent] == true) { diff --git a/splitio_platform_interface/lib/impressions/impressions_method_call_handler.dart b/splitio_platform_interface/lib/impressions/impressions_method_call_handler.dart index ea4e4a4..c68e8fd 100644 --- a/splitio_platform_interface/lib/impressions/impressions_method_call_handler.dart +++ b/splitio_platform_interface/lib/impressions/impressions_method_call_handler.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:splitio_platform_interface/method_call_handler.dart'; import 'package:splitio_platform_interface/split_impression.dart'; +/// Handles impressions method calls. class ImpressionsMethodCallHandler extends StreamMethodCallHandler { final _streamController = StreamController(); diff --git a/splitio_platform_interface/lib/method_call_handler.dart b/splitio_platform_interface/lib/method_call_handler.dart index 6ef88ac..3a28da6 100644 --- a/splitio_platform_interface/lib/method_call_handler.dart +++ b/splitio_platform_interface/lib/method_call_handler.dart @@ -1,7 +1,11 @@ +/// Abstract class for handling method calls. abstract class MethodCallHandler { + /// Handles a method call with the given method name and arguments. Future handle(String methodName, dynamic methodArguments); } +/// Abstract class for handling stream method calls. abstract class StreamMethodCallHandler extends MethodCallHandler { + /// Returns a stream of the given type. Stream stream(); } diff --git a/splitio_platform_interface/lib/method_channel_platform.dart b/splitio_platform_interface/lib/method_channel_platform.dart index aaf0b2c..0d66439 100644 --- a/splitio_platform_interface/lib/method_channel_platform.dart +++ b/splitio_platform_interface/lib/method_channel_platform.dart @@ -6,7 +6,9 @@ const String _controlTreatment = 'control'; const SplitResult _controlResult = SplitResult(_controlTreatment, null); const MethodChannel _methodChannel = MethodChannel('splitio'); +/// Method channel platform implementation. class MethodChannelPlatform extends SplitioPlatform { + /// Returns the method channel. MethodChannel get methodChannel => _methodChannel; final Map _handlers = {}; @@ -15,6 +17,8 @@ class MethodChannelPlatform extends SplitioPlatform { ImpressionsMethodCallHandler(); @visibleForTesting + + /// Handles method calls from the platform. Future handle(MethodCall call) async { _impressionsMethodCallHandler.handle(call.method, call.arguments); for (MethodCallHandler handler in _handlers.values) { diff --git a/splitio_platform_interface/lib/split_certificate_pinning_configuration.dart b/splitio_platform_interface/lib/split_certificate_pinning_configuration.dart index 78b9a0b..0c9f839 100644 --- a/splitio_platform_interface/lib/split_certificate_pinning_configuration.dart +++ b/splitio_platform_interface/lib/split_certificate_pinning_configuration.dart @@ -1,9 +1,11 @@ +/// Certificate pinning configuration. class CertificatePinningConfiguration { - final Map> _pins = {}; + /// Returns the pins. Map> get pins => _pins; + /// Adds a pin for the given host. CertificatePinningConfiguration addPin(String host, String pin) { pin = pin.trim(); if (pin.isEmpty) { @@ -17,4 +19,4 @@ class CertificatePinningConfiguration { _pins[host]?.add(pin); return this; } -} \ No newline at end of file +} diff --git a/splitio_platform_interface/lib/split_configuration.dart b/splitio_platform_interface/lib/split_configuration.dart index c742c48..90ce1be 100644 --- a/splitio_platform_interface/lib/split_configuration.dart +++ b/splitio_platform_interface/lib/split_configuration.dart @@ -3,7 +3,9 @@ import 'package:splitio_platform_interface/split_fallback_treatments_configurati import 'package:splitio_platform_interface/split_sync_config.dart'; import 'package:splitio_platform_interface/split_rollout_cache_configuration.dart'; +/// Split configuration. class SplitConfiguration { + /// The configuration map. final Map configurationMap = {}; /// Initializes the Split configuration. @@ -211,16 +213,49 @@ class SplitConfiguration { } } +/// Impressions mode. enum ImpressionsMode { + /// Debug impressions mode. debug, + + /// Optimized impressions mode. optimized, + + /// None impressions mode. none, } +/// User consent. enum UserConsent { + /// The user grants consent for tracking events and impressions. The SDK sends them to Split cloud. granted, + + /// The user declines consent for tracking events and impressions. The SDK does not send them to Split cloud. declined, + + /// The user neither grants nor declines consent for tracking events and impressions. The SDK tracks them in its + /// internal storage, and eventually either sends them or not if the consent status is updated to 'GRANTED' or + /// 'DECLINED' respectively. The status can be updated at any time with the `UserConsent.setStatus` factory method. unknown, } -enum SplitLogLevel { verbose, debug, info, warning, error, none } +/// Split log level. +enum SplitLogLevel { + /// Verbose log level. + verbose, + + /// Debug log level. + debug, + + /// Info log level. + info, + + /// Warning log level. + warning, + + /// Error log level. + error, + + /// None log level. + none +} diff --git a/splitio_platform_interface/lib/split_evaluation_options.dart b/splitio_platform_interface/lib/split_evaluation_options.dart index 2a603a8..9986514 100644 --- a/splitio_platform_interface/lib/split_evaluation_options.dart +++ b/splitio_platform_interface/lib/split_evaluation_options.dart @@ -1,17 +1,22 @@ import 'dart:collection'; +/// Options for evaluation. class EvaluationOptions { final Map _properties; + /// Impression properties. Map get properties => UnmodifiableMapView(_properties); + /// Creates a new EvaluationOptions instance. const EvaluationOptions.empty() : _properties = const {}; + /// Creates a new EvaluationOptions instance. factory EvaluationOptions([Map properties = const {}]) { return EvaluationOptions._( Map.unmodifiable(Map.from(properties))); } + /// Converts the EvaluationOptions to a JSON map. Map toJson() => { 'properties': _properties, }; diff --git a/splitio_platform_interface/lib/split_fallback_treatment.dart b/splitio_platform_interface/lib/split_fallback_treatment.dart index bb52ed9..bca1dc5 100644 --- a/splitio_platform_interface/lib/split_fallback_treatment.dart +++ b/splitio_platform_interface/lib/split_fallback_treatment.dart @@ -1,6 +1,11 @@ +/// Fallback treatment for when the feature flag cannot be evaluated. class FallbackTreatment { + /// The treatment value. final String treatment; + + /// The treatment configuration. final String? config; + /// Creates a new FallbackTreatment instance. const FallbackTreatment(this.treatment, [this.config]); } diff --git a/splitio_platform_interface/lib/split_fallback_treatments_configuration.dart b/splitio_platform_interface/lib/split_fallback_treatments_configuration.dart index d3c3c8d..3281ae5 100644 --- a/splitio_platform_interface/lib/split_fallback_treatments_configuration.dart +++ b/splitio_platform_interface/lib/split_fallback_treatments_configuration.dart @@ -1,12 +1,17 @@ import 'package:splitio_platform_interface/split_fallback_treatment.dart'; +/// Configuration for fallback treatments. class FallbackTreatmentsConfiguration { Map? _global; Map>? _byFlag; + /// Global fallback treatment. Map? get global => _global; + + /// Fallback treatments by flag. Map>? get byFlag => _byFlag; + /// Creates a new FallbackTreatmentsConfiguration instance. FallbackTreatmentsConfiguration( {FallbackTreatment? global, Map? byFlag}) { _global = global != null diff --git a/splitio_platform_interface/lib/split_impression.dart b/splitio_platform_interface/lib/split_impression.dart index b3df44d..de7c15b 100644 --- a/splitio_platform_interface/lib/split_impression.dart +++ b/splitio_platform_interface/lib/split_impression.dart @@ -1,17 +1,37 @@ +/// Represents an impression when a feature flag is evaluated. class Impression { + /// The traffic matching key. final String? key; + + /// The traffic bucketing key. final String? bucketingKey; + + /// The name of the feature flag. final String? split; + + /// The treatment value. final String? treatment; + + /// The impression timestamp. final num? time; + + /// The rule label. final String? appliedRule; + + /// The version of the feature flag. final num? changeNumber; + + /// The attributes. final Map attributes; + + /// The impression properties. final Map? properties; + /// Creates a new Impression instance. Impression(this.key, this.bucketingKey, this.split, this.treatment, this.time, this.appliedRule, this.changeNumber, this.attributes, this.properties); + /// Creates a new Impression instance from a map. static Impression fromMap(Map map) { Map? properties; if (map['properties'] != null) { diff --git a/splitio_platform_interface/lib/split_prerequisite.dart b/splitio_platform_interface/lib/split_prerequisite.dart index b8be081..611436c 100644 --- a/splitio_platform_interface/lib/split_prerequisite.dart +++ b/splitio_platform_interface/lib/split_prerequisite.dart @@ -1,14 +1,19 @@ +/// Prerequisite class. class Prerequisite { final String _name; final Set _treatments; + /// The feature flag name of the prerequisite. String get name => _name; + /// The treatments of the prerequisite. Set get treatments => _treatments; + /// Creates a new Prerequisite instance. Prerequisite(this._name, this._treatments); + /// Creates a Prerequisite instance from a map. static Prerequisite fromEntry(el) { final String name = (el['n'] ?? el['n:'] ?? '').toString(); final List rawTreatments = (el['t'] as List?) ?? []; @@ -26,6 +31,7 @@ class Prerequisite { }'''; } + /// Checks if this Prerequisite is equal to another Prerequisite. equals(Prerequisite other) { return name == other.name && treatments == other.treatments; } diff --git a/splitio_platform_interface/lib/split_result.dart b/splitio_platform_interface/lib/split_result.dart index f1c0896..fe6c4fc 100644 --- a/splitio_platform_interface/lib/split_result.dart +++ b/splitio_platform_interface/lib/split_result.dart @@ -4,9 +4,13 @@ /// /// The [config] contains the configuration for the split, if any. May be null. class SplitResult { + /// The treatment of the split. final String treatment; + + /// The configuration of the split, if any. May be null. final String? config; + /// Creates a new SplitResult instance. const SplitResult(this.treatment, this.config); @override diff --git a/splitio_platform_interface/lib/split_rollout_cache_configuration.dart b/splitio_platform_interface/lib/split_rollout_cache_configuration.dart index 9c2b0f3..340bc5d 100644 --- a/splitio_platform_interface/lib/split_rollout_cache_configuration.dart +++ b/splitio_platform_interface/lib/split_rollout_cache_configuration.dart @@ -1,12 +1,17 @@ +/// Rollout cache configuration class. class RolloutCacheConfiguration { - late int _expirationDays; late bool _clearOnInit; + /// The expiration days of the cache. int get expirationDays => _expirationDays; + + /// Whether to clear the cache on initialization. bool get clearOnInit => _clearOnInit; - RolloutCacheConfiguration({int expirationDays = 10, bool clearOnInit = false}) { + /// Creates a new RolloutCacheConfiguration instance. + RolloutCacheConfiguration( + {int expirationDays = 10, bool clearOnInit = false}) { if (expirationDays < 1) { expirationDays = 10; } diff --git a/splitio_platform_interface/lib/split_sync_config.dart b/splitio_platform_interface/lib/split_sync_config.dart index bc47f8d..1b0ed05 100644 --- a/splitio_platform_interface/lib/split_sync_config.dart +++ b/splitio_platform_interface/lib/split_sync_config.dart @@ -1,14 +1,19 @@ +/// Sync configuration class for controlling which feature flags to fetch. class SyncConfig { late Set _names; late Set _prefixes; late Set _sets; + /// Names of the feature flags to fetch. Set get names => _names; + /// Prefixes of the feature flags to fetch. Set get prefixes => _prefixes; + /// Flag sets of the feature flags to fetch. Set get sets => _sets; + /// Creates a new SyncConfig instance passing an optional list of names and prefixes. SyncConfig( {List names = const [], List prefixes = const []}) { _names = names.toSet(); @@ -16,12 +21,14 @@ class SyncConfig { _sets = {}; } + /// Creates a new SyncConfig instance passing an optional set of names and prefixes. SyncConfig.fromSet( {Set names = const {}, Set prefixes = const {}}) { _names = names; _prefixes = prefixes; } + /// Creates a new SyncConfig instance passing a list of flag sets. SyncConfig.flagSets(List sets) { _sets = sets.toSet(); _names = {}; diff --git a/splitio_platform_interface/lib/split_view.dart b/splitio_platform_interface/lib/split_view.dart index 8908cf6..b4a2244 100644 --- a/splitio_platform_interface/lib/split_view.dart +++ b/splitio_platform_interface/lib/split_view.dart @@ -2,6 +2,7 @@ import 'dart:core'; import 'package:splitio_platform_interface/split_prerequisite.dart'; +/// Represents a feature flag class SplitView { static const String _keyName = 'name'; static const String _keyTrafficType = 'trafficType'; @@ -14,17 +15,37 @@ class SplitView { static const String _keyImpressionsDisabled = 'impressionsDisabled'; static const String _keyPrerequisites = 'prerequisites'; + /// The name of the feature flag. String name; + + /// The traffic type of the feature flag. String trafficType; + + /// Whether the feature flag is killed. bool killed = false; + + /// The treatments of the feature flag. List treatments = []; + + /// The change number of the feature flag. int? changeNumber; + + /// The configurations per treatment of the feature flag. Map configs = {}; + + /// The default treatment of the feature flag. String defaultTreatment; + + /// The sets of the feature flag. List sets = []; + + /// Whether impressions are disabled for the feature flag. bool impressionsDisabled = false; + + /// The prerequisites of the feature flag. Set prerequisites = {}; + /// Creates a new SplitView instance. SplitView(this.name, this.trafficType, this.killed, this.treatments, this.changeNumber, this.configs, [this.defaultTreatment = '', @@ -32,6 +53,7 @@ class SplitView { this.impressionsDisabled = false, this.prerequisites = const {}]); + /// Creates a SplitView instance from a map entry. static SplitView? fromEntry(Map? entry) { if (entry == null || entry.isEmpty) { return null; diff --git a/splitio_platform_interface/lib/splitio_platform_interface.dart b/splitio_platform_interface/lib/splitio_platform_interface.dart index 247c3a2..435c1a2 100644 --- a/splitio_platform_interface/lib/splitio_platform_interface.dart +++ b/splitio_platform_interface/lib/splitio_platform_interface.dart @@ -222,12 +222,14 @@ abstract class _ClientPlatform { /// [SplitioPlatform] methods. abstract class SplitioPlatform extends PlatformInterface with _FactoryPlatform, _ClientPlatform { + /// Creates a new SplitioPlatform instance. SplitioPlatform() : super(token: _token); static SplitioPlatform _instance = MethodChannelPlatform(); static final Object _token = Object(); + /// The instance of SplitioPlatform that is used to communicate with the native platform. static SplitioPlatform get instance => _instance; /// Platform-specific plugins should set this with their own platform-specific diff --git a/splitio_web/analysis_options.yaml b/splitio_web/analysis_options.yaml index a5744c1..5cf0db1 100644 --- a/splitio_web/analysis_options.yaml +++ b/splitio_web/analysis_options.yaml @@ -2,3 +2,7 @@ include: package:flutter_lints/flutter.yaml # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options + +linter: + rules: + - public_member_api_docs diff --git a/splitio_web/lib/src/js_interop.dart b/splitio_web/lib/src/js_interop.dart index 4d5076d..42bf8d1 100644 --- a/splitio_web/lib/src/js_interop.dart +++ b/splitio_web/lib/src/js_interop.dart @@ -3,6 +3,7 @@ import 'package:splitio_platform_interface/splitio_platform_interface.dart'; // JS SDK types +/// SplitIO.ImpressionDTO @JS() extension type JSImpressionDTO._(JSObject _) implements JSObject { external JSString feature; @@ -16,6 +17,7 @@ extension type JSImpressionDTO._(JSObject _) implements JSObject { external JSString? properties; } +/// SplitIO.ImpressionData @JS() extension type JSImpressionData._(JSObject _) implements JSObject { external JSImpressionDTO impression; @@ -25,30 +27,43 @@ extension type JSImpressionData._(JSObject _) implements JSObject { external JSString sdkLanguageVersion; } +/// SplitIO.ILogger @JS() extension type JSILogger._(JSObject _) implements JSObject { + /// Log a debug level message external JSAny? debug(JSString message); + + /// Log an info level message external JSAny? info(JSString message); + + /// Log a warning level message external JSAny? warn(JSString message); + + /// Log an error level message external JSAny? error(JSString message); } +/// SplitIO.IImpressionListener @JS() extension type JSImpressionListener._(JSObject _) implements JSObject { + /// Log an impression external JSVoid logImpression(JSImpressionData impression); } +/// SplitIO.IClientSideSettings['core'] @JS() extension type JSConfigurationCore._(JSObject _) implements JSObject { external JSString authorizationKey; external JSAny key; // string | SplitKey } +/// SplitIO.IClientSideSettings['startup'] @JS() extension type JSConfigurationStartup._(JSObject _) implements JSObject { external JSNumber? readyTimeout; } +/// SplitIO.IClientSideSettings['scheduler'] @JS() extension type JSConfigurationScheduler._(JSObject _) implements JSObject { external JSNumber? featuresRefreshRate; @@ -61,6 +76,7 @@ extension type JSConfigurationScheduler._(JSObject _) implements JSObject { external JSNumber? eventsPushRate; } +/// SplitIO.IClientSideSettings['urls'] @JS() extension type JSConfigurationUrls._(JSObject _) implements JSObject { external JSString? sdk; @@ -70,12 +86,14 @@ extension type JSConfigurationUrls._(JSObject _) implements JSObject { external JSString? telemetry; } +/// SplitIO.IClientSideSettings['sync']['splitFilters'] @JS() extension type JSSplitFilter._(JSObject _) implements JSObject { external JSString type; external JSArray values; } +/// SplitIO.IClientSideSettings['sync'] @JS() extension type JSConfigurationSync._(JSObject _) implements JSObject { external JSString? impressionsMode; @@ -83,6 +101,7 @@ extension type JSConfigurationSync._(JSObject _) implements JSObject { external JSArray? splitFilters; } +/// SplitIO.IClientSideSettings['storage'] @JS() extension type JSConfigurationStorage._(JSObject _) implements JSObject { external JSString? type; @@ -90,12 +109,15 @@ extension type JSConfigurationStorage._(JSObject _) implements JSObject { external JSBoolean? clearOnInit; } +/// SplitIO.IClientSideSettings['fallbackTreatments'] @JS() -extension type JSFallbackTreatmentsConfiguration._(JSObject _) implements JSObject { +extension type JSFallbackTreatmentsConfiguration._(JSObject _) + implements JSObject { external JSTreatmentWithConfig? global; external JSObject? byFlag; } +/// SplitIO.IClientSideSettings @JS() extension type JSConfiguration._(JSObject _) implements JSObject { external JSConfigurationCore core; @@ -111,18 +133,24 @@ extension type JSConfiguration._(JSObject _) implements JSObject { external JSFallbackTreatmentsConfiguration? fallbackTreatments; } +/// SplitIO.ISettings @JS() extension type JSISettings._(JSObject _) implements JSConfiguration { external JSILogger log; external JSImpressionListener? impressionListener; } +/// SplitIO.IUserConsentAPI @JS() extension type JSIUserConsentAPI._(JSObject _) implements JSObject { + /// SplitIO.IUserConsentAPI['setStatus'] external JSBoolean setStatus(JSBoolean userConsent); + + /// SplitIO.IUserConsentAPI['getStatus'] external JSString getStatus(); } +/// SplitIO.EventConsts @JS() extension type JSEventConsts._(JSObject _) implements JSObject { // ignore: non_constant_identifier_names @@ -135,6 +163,7 @@ extension type JSEventConsts._(JSObject _) implements JSObject { external JSString SDK_UPDATE; } +/// SplitIO.ReadinessStatus @JS() extension type JSReadinessStatus._(JSObject _) implements JSObject { external JSBoolean isReady; @@ -142,18 +171,21 @@ extension type JSReadinessStatus._(JSObject _) implements JSObject { external JSBoolean hasTimedout; } +/// SplitIO.TreatmentWithConfig @JS() extension type JSTreatmentWithConfig._(JSObject _) implements JSObject { external JSString treatment; external JSString? config; } +/// SplitIO.SplitView['prerequisites'] @JS() extension type JSPrerequisite._(JSObject _) implements JSObject { external JSString flagName; external JSArray treatments; } +/// SplitIO.SplitView @JS() extension type JSSplitView._(JSObject _) implements JSObject { external JSString name; @@ -168,73 +200,132 @@ extension type JSSplitView._(JSObject _) implements JSObject { external JSArray prerequisites; } +/// SplitIO.EvaluationOptions @JS() extension type JSEvaluationOptions._(JSObject _) implements JSObject { external JSObject properties; } +/// SplitIO.IBrowserClient @JS() extension type JSIBrowserClient._(JSObject _) implements JSObject { + /// SplitIO.IBrowserClient['getTreatment'] external JSString getTreatment(JSString flagName, JSObject attributes, JSEvaluationOptions evaluationOptions); + + /// SplitIO.IBrowserClient['getTreatments'] external JSObject getTreatments(JSArray flagNames, JSObject attributes, JSEvaluationOptions evaluationOptions); + + /// SplitIO.IBrowserClient['getTreatmentWithConfig'] external JSTreatmentWithConfig getTreatmentWithConfig(JSString flagName, JSObject attributes, JSEvaluationOptions evaluationOptions); + + /// SplitIO.IBrowserClient['getTreatmentsWithConfig'] external JSObject getTreatmentsWithConfig(JSArray flagNames, JSObject attributes, JSEvaluationOptions evaluationOptions); + + /// SplitIO.IBrowserClient['getTreatmentsByFlagSet'] external JSObject getTreatmentsByFlagSet(JSString flagSetName, JSObject attributes, JSEvaluationOptions evaluationOptions); + + /// SplitIO.IBrowserClient['getTreatmentsByFlagSets'] external JSObject getTreatmentsByFlagSets(JSArray flagSetNames, JSObject attributes, JSEvaluationOptions evaluationOptions); + + /// SplitIO.IBrowserClient['getTreatmentsWithConfigByFlagSet'] external JSObject getTreatmentsWithConfigByFlagSet(JSString flagSetName, JSObject attributes, JSEvaluationOptions evaluationOptions); + + /// SplitIO.IBrowserClient['getTreatmentsWithConfigByFlagSets'] external JSObject getTreatmentsWithConfigByFlagSets( JSArray flagSetNames, JSObject attributes, JSEvaluationOptions evaluationOptions); + + /// SplitIO.IBrowserClient['track'] external JSBoolean track(JSString? trafficType, JSString eventType, JSNumber? value, JSObject? attributes); + + /// SplitIO.IBrowserClient['setAttribute'] external JSBoolean setAttribute( JSString attributeName, JSAny? attributeValue); + + /// SplitIO.IBrowserClient['getAttribute'] external JSAny getAttribute(JSString attributeName); + + /// SplitIO.IBrowserClient['removeAttribute'] external JSBoolean removeAttribute(JSString attributeName); + + /// SplitIO.IBrowserClient['setAttributes'] external JSBoolean setAttributes(JSObject attributes); + + /// SplitIO.IBrowserClient['getAttributes'] external JSObject getAttributes(); + + /// SplitIO.IBrowserClient['clearAttributes'] external JSBoolean clearAttributes(); + + /// SplitIO.IBrowserClient['flush'] external JSPromise flush(); + + /// SplitIO.IBrowserClient['destroy'] external JSPromise destroy(); + + /// SplitIO.IBrowserClient['on'] external JSVoid on(JSString event, JSFunction listener); + + /// SplitIO.IBrowserClient['off'] external JSVoid off(JSString event, JSFunction listener); + + /// SplitIO.IBrowserClient['emit'] external JSVoid emit(JSString event); // ignore: non_constant_identifier_names external JSEventConsts Event; + + /// SplitIO.IBrowserClient['getStatus'] external JSReadinessStatus getStatus(); } +/// SplitIO.IManager @JS() extension type JSIManager._(JSObject _) implements JSObject { + /// SplitIO.IManager['names'] external JSArray names(); + + /// SplitIO.IManager['split'] external JSSplitView? split(JSString name); + + /// SplitIO.IManager['splits'] external JSArray splits(); } +/// SplitIO.IBrowserSDK @JS() extension type JSIBrowserSDK._(JSObject _) implements JSObject { + /// SplitIO.IBrowserSDK['client'] external JSIBrowserClient client(JSAny? key); + + /// SplitIO.IBrowserSDK['manager'] external JSIManager manager(); + + /// SplitIO.IBrowserSDK['settings'] external JSISettings settings; // ignore: non_constant_identifier_names external JSIUserConsentAPI UserConsent; } +/// SplitIO.LoggerFactory @JS() extension type JSLoggerFactory._(JSFunction _) implements JSFunction { + /// A callable function external JSObject call(); } +/// Type of the `window.splitio` object @JS() extension type JSBrowserSDKPackage._(JSObject _) implements JSObject { + /// Browser SDK factory constructor // ignore: non_constant_identifier_names external JSIBrowserSDK SplitFactory(JSConfiguration config); // ignore: non_constant_identifier_names @@ -251,41 +342,52 @@ extension type JSBrowserSDKPackage._(JSObject _) implements JSObject { // Conversion utils: JS to Dart types +/// Get the keys of a JavaScript object @JS('Object.keys') external JSArray objectKeys(JSObject obj); +/// Get a property from a JavaScript object @JS('Reflect.get') external JSAny? reflectGet(JSObject target, JSString propertyKey); +/// Set a property on a JavaScript object @JS('Reflect.set') external JSAny? reflectSet(JSObject target, JSString propertyKey, JSAny? value); +/// Parse a JSON string into a JavaScript object @JS('JSON.parse') external JSObject jsonParse(JSString obj); +/// Convert a JavaScript array to a Dart list List jsArrayToList(JSArray obj) => (obj.dartify() as List).cast(); +/// Convert a JavaScript object to a Dart map Map jsObjectToMap(JSObject obj) => (obj.dartify() as Map).cast(); +/// Convert a JavaScript value to a Dart value Object? jsAnyToDart(JSAny? value) => value.dartify(); // Conversion utils: JS SDK to Flutter SDK types +/// Convert a JavaScript SplitIO.Treatments object to a Dart map Map jsTreatmentsToMap(JSObject obj) { return jsObjectToMap(obj).map((k, v) => MapEntry(k, v as String)); } +/// Convert a JavaScript SplitIO.TreatmentsWithConfig object to a Dart map Map jsTreatmentsWithConfigToMap(JSObject obj) { return jsObjectToMap(obj).map((k, v) => MapEntry( k, SplitResult(v['treatment'] as String, v['config'] as String?))); } +/// Convert a JavaScript SplitIO.TreatmentWithConfig object to a Dart SplitResult SplitResult jsTreatmentWithConfigToSplitResult(JSTreatmentWithConfig obj) { return SplitResult(obj.treatment.toDart, obj.config?.toDart); } +/// Convert a JavaScript prerequisite object to a Dart Prerequisite Prerequisite jsPrerequisiteToPrerequisite(JSPrerequisite obj) { return Prerequisite( obj.flagName.toDart, @@ -293,6 +395,7 @@ Prerequisite jsPrerequisiteToPrerequisite(JSPrerequisite obj) { ); } +/// Convert a JavaScript SplitIO.SplitView object to a Dart SplitView SplitView jsSplitViewToSplitView(JSSplitView obj) { return SplitView( obj.name.toDart, @@ -307,6 +410,7 @@ SplitView jsSplitViewToSplitView(JSSplitView obj) { obj.prerequisites.toDart.map(jsPrerequisiteToPrerequisite).toSet()); } +/// Convert a JavaScript SplitIO.ImpressionData object to a Dart Impression Impression jsImpressionDataToImpression(JSImpressionData obj) { return Impression( obj.impression.keyName.toDart, @@ -323,6 +427,7 @@ Impression jsImpressionDataToImpression(JSImpressionData obj) { ); } +/// Build a JavaScript SplitIO.SplitKey object from a matching key and optional bucketing key JSAny buildJsKey(String matchingKey, String? bucketingKey) { if (bucketingKey != null) { return { @@ -333,6 +438,7 @@ JSAny buildJsKey(String matchingKey, String? bucketingKey) { return matchingKey.toJS; } +/// Build a string index from a matching key and optional bucketing key String buildKeyString(String matchingKey, String? bucketingKey) { return bucketingKey == null ? matchingKey : '${matchingKey}_$bucketingKey'; } From 98fc51979345e8be257b1c510240ca9c89e12816 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Wed, 28 Jan 2026 17:04:49 -0300 Subject: [PATCH 13/13] Update CHANGELOG entries --- splitio/CHANGELOG.md | 23 +++++++++++++------ splitio/example/pubspec.lock | 18 +++++++-------- splitio/pubspec.yaml | 10 ++++---- splitio_android/CHANGELOG.md | 6 ++++- splitio_android/pubspec.yaml | 4 ++-- splitio_ios/CHANGELOG.md | 6 ++++- splitio_ios/pubspec.yaml | 4 ++-- splitio_platform_interface/CHANGELOG.md | 3 +++ .../lib/split_prerequisite.dart | 4 ++-- splitio_platform_interface/pubspec.yaml | 2 +- splitio_web/CHANGELOG.md | 11 ++++++++- splitio_web/lib/splitio_web.dart | 2 +- splitio_web/pubspec.yaml | 6 ++--- ....full.min.js => split-browser.full.min.js} | 0 14 files changed, 64 insertions(+), 35 deletions(-) rename splitio_web/web/{split-browser-1.6.1.full.min.js => split-browser.full.min.js} (100%) diff --git a/splitio/CHANGELOG.md b/splitio/CHANGELOG.md index 01e41b7..371938a 100644 --- a/splitio/CHANGELOG.md +++ b/splitio/CHANGELOG.md @@ -1,17 +1,26 @@ +# 1.2.1 (Jan 28, 2026) +* Bug fix: corrected asset path for loading the Browser SDK. + +# 1.2.1-rc.1 (Jan 28, 2026) + +# 1.2.0 (Jan 28, 2026) +* Added new configuration for Fallback Treatments, which allows setting a treatment value and optional config to be returned in place of "control", either globally or by flag. Read more in our docs. +* Updated Android SDK to `5.4.2`, iOS SDK to `3.6.0`, and Browser SDK to `1.6.1` + # 1.2.0-rc.1 (Jan 28, 2026) # 1.1.0 (Jan 16, 2026) -- Added Web support via the `splitio_web` package, the Web implementation of `splitio` based on the Split Browser SDK `1.6.0`. +* Added Web support via the `splitio_web` package, the Web implementation of `splitio` based on the Split Browser SDK `1.6.0`. # 1.1.0-rc.1 (Jan 15, 2026) # 1.0.0 (Aug 14, 2025) -- Updated Android SDK to `5.3.1` & iOS SDK to `3.3.2` -- Added support for rule-based segments. These segments determine membership at runtime by evaluating their configured rules against the user attributes provided to the SDK. -- Added support for feature flag prerequisites. This allows customers to define dependency conditions between flags, which are evaluated before any allowlists or targeting rules. -- Added two new configuration options to control the behavior of the persisted rollout plan cache. Use `rolloutCacheConfiguration` in the config. -- Added a new optional argument to the client `getTreatment` methods to allow passing additional evaluation options, such as a map of properties to append to the generated impressions sent to Split backend. Read more in our docs. -- Added support for the new impressions tracking toggle available on feature flags, both respecting the setting and including the new field being returned on SplitView type objects. Read more in our docs. +* Updated Android SDK to `5.3.1` & iOS SDK to `3.3.2` +* Added support for rule-based segments. These segments determine membership at runtime by evaluating their configured rules against the user attributes provided to the SDK. +* Added support for feature flag prerequisites. This allows customers to define dependency conditions between flags, which are evaluated before any allowlists or targeting rules. +* Added two new configuration options to control the behavior of the persisted rollout plan cache. Use `rolloutCacheConfiguration` in the config. +* Added a new optional argument to the client `getTreatment` methods to allow passing additional evaluation options, such as a map of properties to append to the generated impressions sent to Split backend. Read more in our docs. +* Added support for the new impressions tracking toggle available on feature flags, both respecting the setting and including the new field being returned on SplitView type objects. Read more in our docs. # 1.0.0-rc.1 (Aug 14, 2025) diff --git a/splitio/example/pubspec.lock b/splitio/example/pubspec.lock index 2e7d49c..c944234 100644 --- a/splitio/example/pubspec.lock +++ b/splitio/example/pubspec.lock @@ -171,39 +171,39 @@ packages: path: ".." relative: true source: path - version: "1.1.0" + version: "1.2.1" splitio_android: dependency: transitive description: name: splitio_android - sha256: "344bf82de6694cffb8dd80a96ee734e31bb838d2b4693fb046e0fc98e31512ca" + sha256: "7c0e5ad4ccdf4990120a7a6a2f067d274c107ab9830fd20b1d54bf3f0392ac02" url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.1.0" splitio_ios: dependency: transitive description: name: splitio_ios - sha256: "1c078bc49bf7b30df6ca50accb6a9eecf592ec607e20e77b1c6ecdabc7a44dc9" + sha256: c15cd7dfd195df107ae07c030fd742dcabb0610c769466d6d7e3890d22a91bc2 url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.1.0" splitio_platform_interface: dependency: transitive description: name: splitio_platform_interface - sha256: "8bcb1cab9f5fffb7b79cfeeaf6c80d82f8ede55c8d6ca7578ec78653f3f9e499" + sha256: faa022814c7b2fc7b5f68b80b088e1638e06783419075176d1adadcf787897db url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.1.0" splitio_web: dependency: transitive description: name: splitio_web - sha256: "29dc1a55d80c026afb0f0bad378c81e44ee1e9da5faaf9e931f35b5dfd3ff5f3" + sha256: "656cf71d4ec900cf1ad1b9eae20bbabe797de5c99f49584672161de9fe133afb" url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.1.1" stack_trace: dependency: transitive description: diff --git a/splitio/pubspec.yaml b/splitio/pubspec.yaml index 3166761..89f2b62 100644 --- a/splitio/pubspec.yaml +++ b/splitio/pubspec.yaml @@ -1,6 +1,6 @@ name: splitio description: Official plugin for split.io, the platform for controlled rollouts, which serves features to your users via feature flags to manage your complete customer experience. -version: 1.2.0-rc.1 +version: 1.2.1 homepage: https://split.io/ repository: https://github.com/splitio/flutter-sdk-plugin/tree/main/splitio/ @@ -21,10 +21,10 @@ flutter: dependencies: flutter: sdk: flutter - splitio_android: ^1.1.0-rc.1 - splitio_ios: ^1.1.0-rc.1 - splitio_web: ^1.1.0-rc.1 - splitio_platform_interface: ^2.1.0-rc.1 + splitio_android: ^1.1.0 + splitio_ios: ^1.1.0 + splitio_web: ^1.1.1 + splitio_platform_interface: ^2.1.0 dev_dependencies: flutter_test: sdk: flutter diff --git a/splitio_android/CHANGELOG.md b/splitio_android/CHANGELOG.md index a6a85b8..aa4545a 100644 --- a/splitio_android/CHANGELOG.md +++ b/splitio_android/CHANGELOG.md @@ -1,7 +1,11 @@ +# 1.1.0 (Jan 28, 2026) +* Added new configuration for Fallback Treatments, which allows setting a treatment value and optional config to be returned in place of "control", either globally or by flag. Read more in our docs. +* Updated Android SDK to `5.4.2`. + # 1.1.0-rc.1 (Jan 28, 2026) # 1.0.0 (Aug 14, 2025) -- Updated Android SDK to `5.3.1`. +* Updated Android SDK to `5.3.1`. # 1.0.0-rc.1 (Aug 14, 2025) diff --git a/splitio_android/pubspec.yaml b/splitio_android/pubspec.yaml index 463872b..772cc56 100644 --- a/splitio_android/pubspec.yaml +++ b/splitio_android/pubspec.yaml @@ -1,7 +1,7 @@ name: splitio_android description: The official Android implementation of splitio Flutter plugin. repository: https://github.com/splitio/flutter-sdk-plugin/tree/main/splitio_android -version: 1.1.0-rc.1 +version: 1.1.0 environment: sdk: ">=2.16.2 <4.0.0" @@ -19,7 +19,7 @@ flutter: dependencies: flutter: sdk: flutter - splitio_platform_interface: ^2.1.0-rc.1 + splitio_platform_interface: ^2.1.0 dev_dependencies: flutter_test: diff --git a/splitio_ios/CHANGELOG.md b/splitio_ios/CHANGELOG.md index f72181d..6262687 100644 --- a/splitio_ios/CHANGELOG.md +++ b/splitio_ios/CHANGELOG.md @@ -1,7 +1,11 @@ +# 1.1.0 (Jan 28, 2026) +* Added new configuration for Fallback Treatments, which allows setting a treatment value and optional config to be returned in place of "control", either globally or by flag. Read more in our docs. +* Updated iOS SDK to `3.6.0`. + # 1.1.0-rc.1 (Jan 28, 2026) # 1.0.0 (Aug 14, 2025) -- iOS SDK to `3.3.2` +* Updated iOS SDK to `3.3.2` # 1.0.0-rc.1 (Aug 14, 2025) diff --git a/splitio_ios/pubspec.yaml b/splitio_ios/pubspec.yaml index e986ac0..5035e48 100644 --- a/splitio_ios/pubspec.yaml +++ b/splitio_ios/pubspec.yaml @@ -1,7 +1,7 @@ name: splitio_ios description: The official iOS implementation of splitio Flutter plugin. repository: https://github.com/splitio/flutter-sdk-plugin/tree/main/splitio_ios -version: 1.1.0-rc.1 +version: 1.1.0 environment: sdk: ">=2.16.2 <4.0.0" @@ -18,7 +18,7 @@ flutter: dependencies: flutter: sdk: flutter - splitio_platform_interface: ^2.1.0-rc.1 + splitio_platform_interface: ^2.1.0 dev_dependencies: flutter_test: diff --git a/splitio_platform_interface/CHANGELOG.md b/splitio_platform_interface/CHANGELOG.md index 9402aa4..7088e82 100644 --- a/splitio_platform_interface/CHANGELOG.md +++ b/splitio_platform_interface/CHANGELOG.md @@ -1,3 +1,6 @@ +# 2.1.0 (Jan 28, 2026) +* Added new configuration for Fallback Treatments, which allows setting a treatment value and optional config to be returned in place of "control", either globally or by flag. Read more in our docs. + # 2.1.0-rc.1 (Jan 28, 2026) # 2.0.0 (Aug 14, 2025) diff --git a/splitio_platform_interface/lib/split_prerequisite.dart b/splitio_platform_interface/lib/split_prerequisite.dart index 611436c..02e47df 100644 --- a/splitio_platform_interface/lib/split_prerequisite.dart +++ b/splitio_platform_interface/lib/split_prerequisite.dart @@ -14,7 +14,7 @@ class Prerequisite { Prerequisite(this._name, this._treatments); /// Creates a Prerequisite instance from a map. - static Prerequisite fromEntry(el) { + static Prerequisite fromEntry(Map el) { final String name = (el['n'] ?? el['n:'] ?? '').toString(); final List rawTreatments = (el['t'] as List?) ?? []; final Set treatments = @@ -32,7 +32,7 @@ class Prerequisite { } /// Checks if this Prerequisite is equal to another Prerequisite. - equals(Prerequisite other) { + bool equals(Prerequisite other) { return name == other.name && treatments == other.treatments; } diff --git a/splitio_platform_interface/pubspec.yaml b/splitio_platform_interface/pubspec.yaml index 5273aa5..411ef85 100644 --- a/splitio_platform_interface/pubspec.yaml +++ b/splitio_platform_interface/pubspec.yaml @@ -2,7 +2,7 @@ name: splitio_platform_interface description: A common platform interface for the splitio plugin. # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.1.0-rc.1 +version: 2.1.0 repository: https://github.com/splitio/flutter-sdk-plugin/tree/main/splitio_platform_interface environment: diff --git a/splitio_web/CHANGELOG.md b/splitio_web/CHANGELOG.md index f9989b9..1ef2281 100644 --- a/splitio_web/CHANGELOG.md +++ b/splitio_web/CHANGELOG.md @@ -1,6 +1,15 @@ +# 1.1.1 (Jan 28, 2026) +* Bug fix: corrected asset path for loading the Browser SDK. + +# 1.1.1-rc.1 (Jan 28, 2026) + +# 1.1.0 (Jan 28, 2026) +* Added new configuration for Fallback Treatments, which allows setting a treatment value and optional config to be returned in place of "control", either globally or by flag. Read more in our docs. +* Updated Browser SDK to `1.6.1`. + # 1.1.0-rc.1 (Jan 28, 2026) # 1.0.0 (Jan 16, 2026) -- Initial release. Web implementation of `splitio` based on Split Browser SDK `1.6.0`. +* Initial release. Web implementation of `splitio` based on Split Browser SDK `1.6.0`. # 1.0.0-rc.1 (Jan 15, 2026) diff --git a/splitio_web/lib/splitio_web.dart b/splitio_web/lib/splitio_web.dart index 799fe0b..0e77822 100644 --- a/splitio_web/lib/splitio_web.dart +++ b/splitio_web/lib/splitio_web.dart @@ -91,7 +91,7 @@ class SplitioWeb extends SplitioPlatform { final script = document.createElement('script') as HTMLScriptElement; script.type = 'text/javascript'; script.src = - 'assets/packages/splitio_web/web/split-browser-1.6.0.full.min.js'; + 'assets/packages/splitio_web/web/split-browser.full.min.js'; // Wait for script to load final completer = Completer(); diff --git a/splitio_web/pubspec.yaml b/splitio_web/pubspec.yaml index 7294cb4..452b2d2 100644 --- a/splitio_web/pubspec.yaml +++ b/splitio_web/pubspec.yaml @@ -1,7 +1,7 @@ name: splitio_web description: The official Web implementation of splitio Flutter plugin. repository: https://github.com/splitio/flutter-sdk-plugin/tree/main/splitio_web -version: 1.1.0-rc.1 +version: 1.1.1 environment: sdk: ">=3.3.0 <4.0.0" # using Dart 3.3+ extension types for JS interop @@ -15,12 +15,12 @@ flutter: pluginClass: SplitioWeb fileName: splitio_web.dart assets: - - web/split-browser-1.6.1.full.min.js + - web/split-browser.full.min.js dependencies: flutter: sdk: flutter - splitio_platform_interface: ^2.1.0-rc.1 + splitio_platform_interface: ^2.1.0 flutter_web_plugins: sdk: flutter web: ">=0.5.0 <2.0.0" diff --git a/splitio_web/web/split-browser-1.6.1.full.min.js b/splitio_web/web/split-browser.full.min.js similarity index 100% rename from splitio_web/web/split-browser-1.6.1.full.min.js rename to splitio_web/web/split-browser.full.min.js