Skip to content

Commit 3170236

Browse files
Add SDK initialization and create factory instance with JS interop
1 parent ab1b3c3 commit 3170236

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

splitio_web/lib/splitio_web.dart

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
1+
import 'dart:async';
2+
import 'dart:js_interop';
3+
import 'dart:js_interop_unsafe';
14
import 'package:flutter_web_plugins/flutter_web_plugins.dart' show Registrar;
25
import 'package:splitio_platform_interface/splitio_platform_interface.dart';
6+
import 'package:splitio_web/src/js_interop.dart';
7+
import 'package:web/web.dart';
8+
9+
extension on Window {
10+
@JS()
11+
external JS_BrowserSDKPackage? splitio;
12+
}
313

414
/// Web implementation of [SplitioPlatform].
515
class SplitioWeb extends SplitioPlatform {
@@ -8,4 +18,85 @@ class SplitioWeb extends SplitioPlatform {
818
SplitioPlatform.instance = SplitioWeb();
919
}
1020

21+
// Future to queue method calls until SDK is initialized
22+
Future<void>? _initFuture;
23+
24+
// Store factory instance
25+
late JS_IBrowserSDK _factory;
26+
27+
@override
28+
Future<void> init({
29+
required String apiKey,
30+
required String matchingKey,
31+
required String? bucketingKey,
32+
SplitConfiguration? sdkConfiguration,
33+
}) async {
34+
if (_initFuture == null) {
35+
_initFuture = this._init(apiKey: apiKey, matchingKey: matchingKey, bucketingKey: bucketingKey, sdkConfiguration: sdkConfiguration);
36+
}
37+
return _initFuture;
38+
}
39+
40+
Future<void> _init({
41+
required String apiKey,
42+
required String matchingKey,
43+
required String? bucketingKey,
44+
SplitConfiguration? sdkConfiguration,
45+
}) async {
46+
await _loadSplitSdk();
47+
48+
final config = _buildConfig(apiKey, matchingKey, bucketingKey, sdkConfiguration);
49+
50+
// Create factory instance
51+
this._factory = window.splitio!.SplitFactory.callAsFunction(null, config) as JS_IBrowserSDK;
52+
53+
return;
54+
}
55+
56+
// Checks whether the Split Browser SDK was manually loaded (`window.splitio != null`).
57+
// If not, loads it by injecting a script tag.
58+
static Future<void> _loadSplitSdk() async {
59+
if (window.splitio != null) {
60+
return; // Already loaded
61+
}
62+
63+
// Create and inject script tag
64+
final script = document.createElement('script') as HTMLScriptElement;
65+
script.type = 'text/javascript';
66+
script.src = 'packages/splitio_web/web/split-browser-1.6.0.full.min.js';
67+
68+
// Wait for script to load
69+
final completer = Completer<void>();
70+
71+
script.onload = (Event event) {
72+
completer.complete();
73+
}.toJS;
74+
75+
script.onerror = (Event event) {
76+
completer.completeError(Exception('Failed to load Split SDK'));
77+
}.toJS;
78+
79+
document.head!.appendChild(script);
80+
81+
await completer.future;
82+
83+
if (window.splitio == null) {
84+
throw Exception('Split Browser SDK failed to initialize after loading');
85+
}
86+
}
87+
88+
// Map SplitConfiguration to JS equivalent object
89+
JSObject _buildConfig(String apiKey, String matchingKey, String? bucketingKey, SplitConfiguration? configuration) {
90+
final core = JSObject();
91+
core.setProperty('authorizationKey'.toJS, apiKey.toJS);
92+
// @TODO: set bucketingKey if provided
93+
core.setProperty('key'.toJS, matchingKey.toJS);
94+
95+
final config = JSObject();
96+
config.setProperty('core'.toJS, core);
97+
98+
// @TODO: complete config
99+
return config;
100+
}
101+
11102
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import 'dart:js_interop';
2+
3+
@JS()
4+
extension type JS_IBrowserSDK._(JSObject _) implements JSObject {}
5+
6+
@JS()
7+
extension type JS_BrowserSDKPackage._(JSObject _) implements JSObject {
8+
external JSFunction SplitFactory;
9+
}

0 commit comments

Comments
 (0)