From 50f8d2c2470bf4a4f6a8e59e923877a51f095981 Mon Sep 17 00:00:00 2001 From: Alan Barker Date: Mon, 21 Apr 2025 11:48:00 -0400 Subject: [PATCH] feat: Add support for WASM --- .../pubspec.lock | 8 ++--- apps/sse_contract_test_service/pubspec.lock | 10 +++++- .../defaults/common_default_config.dart | 2 +- .../common/lib/src/network/http_client.dart | 2 +- .../src/config/defaults/default_config.dart | 2 +- .../lib/launchdarkly_event_source_client.dart | 2 +- .../lib/src/sse_client_html.dart | 28 ++++++++-------- packages/event_source_client/pubspec.yaml | 1 + packages/flutter_client_sdk/example/.metadata | 32 +++++++++---------- .../flutter_client_sdk/example/web/index.html | 25 ++------------- .../defaults/flutter_default_config.dart | 2 +- .../lib/src/flutter_state_detector.dart | 2 +- .../src/lifecycle/js_lifecycle_listener.dart | 12 +++---- packages/flutter_client_sdk/pubspec.yaml | 1 + 14 files changed, 60 insertions(+), 69 deletions(-) diff --git a/apps/flutter_client_contract_test_service/pubspec.lock b/apps/flutter_client_contract_test_service/pubspec.lock index 080febc5..ea8d4112 100644 --- a/apps/flutter_client_contract_test_service/pubspec.lock +++ b/apps/flutter_client_contract_test_service/pubspec.lock @@ -393,28 +393,28 @@ packages: path: "../../packages/common_client" relative: true source: path - version: "1.4.1" + version: "1.5.0" launchdarkly_dart_common: dependency: "direct overridden" description: path: "../../packages/common" relative: true source: path - version: "1.3.0" + version: "1.4.0" launchdarkly_event_source_client: dependency: "direct overridden" description: path: "../../packages/event_source_client" relative: true source: path - version: "1.0.0" + version: "1.1.0" launchdarkly_flutter_client_sdk: dependency: "direct main" description: path: "../../packages/flutter_client_sdk" relative: true source: path - version: "4.9.0" + version: "4.10.0" lints: dependency: "direct dev" description: diff --git a/apps/sse_contract_test_service/pubspec.lock b/apps/sse_contract_test_service/pubspec.lock index 796ff794..66f6128e 100644 --- a/apps/sse_contract_test_service/pubspec.lock +++ b/apps/sse_contract_test_service/pubspec.lock @@ -311,7 +311,7 @@ packages: path: "../../packages/event_source_client" relative: true source: path - version: "1.0.0" + version: "1.1.0" lints: dependency: "direct dev" description: @@ -632,6 +632,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + web: + dependency: transitive + description: + name: web + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" + url: "https://pub.dev" + source: hosted + version: "1.1.1" web_socket_channel: dependency: transitive description: diff --git a/packages/common/lib/src/config/defaults/common_default_config.dart b/packages/common/lib/src/config/defaults/common_default_config.dart index a1482b3b..5d5df9bf 100644 --- a/packages/common/lib/src/config/defaults/common_default_config.dart +++ b/packages/common/lib/src/config/defaults/common_default_config.dart @@ -1,7 +1,7 @@ import '../../ld_logging.dart'; import 'stub_config.dart' if (dart.library.io) 'io_config.dart' - if (dart.library.html) 'js_config.dart'; + if (dart.library.js_interop) 'js_config.dart'; final class DefaultLoggingConfig { final defaultLogLevel = LDLogLevel.info; diff --git a/packages/common/lib/src/network/http_client.dart b/packages/common/lib/src/network/http_client.dart index 5a2993bf..60f54daa 100644 --- a/packages/common/lib/src/network/http_client.dart +++ b/packages/common/lib/src/network/http_client.dart @@ -4,7 +4,7 @@ import '../config/defaults/common_default_config.dart'; import '../config/http_properties.dart'; import 'platform_client/stub_client.dart' if (dart.library.io) 'platform_client/io_client.dart' - if (dart.library.html) 'platform_client/js_client.dart'; + if (dart.library.js_interop) 'platform_client/js_client.dart'; import 'utils.dart'; /// Http requests methods supported by the HTTP client. diff --git a/packages/common_client/lib/src/config/defaults/default_config.dart b/packages/common_client/lib/src/config/defaults/default_config.dart index 65117ec1..6f81dd8d 100644 --- a/packages/common_client/lib/src/config/defaults/default_config.dart +++ b/packages/common_client/lib/src/config/defaults/default_config.dart @@ -1,6 +1,6 @@ import 'stub_config.dart' if (dart.library.io) 'io_config.dart' - if (dart.library.html) 'js_config.dart'; + if (dart.library.js_interop) 'js_config.dart'; /// Configuration common to web and mobile is contained in this file. /// diff --git a/packages/event_source_client/lib/launchdarkly_event_source_client.dart b/packages/event_source_client/lib/launchdarkly_event_source_client.dart index d583feb2..2ca0bef7 100644 --- a/packages/event_source_client/lib/launchdarkly_event_source_client.dart +++ b/packages/event_source_client/lib/launchdarkly_event_source_client.dart @@ -7,7 +7,7 @@ import 'src/http_consts.dart'; import 'src/message_event.dart'; import 'src/sse_client_stub.dart' if (dart.library.io) 'src/sse_client_http.dart' - if (dart.library.html) 'src/sse_client_html.dart'; + if (dart.library.js_interop) 'src/sse_client_html.dart'; export 'src/message_event.dart' show MessageEvent; diff --git a/packages/event_source_client/lib/src/sse_client_html.dart b/packages/event_source_client/lib/src/sse_client_html.dart index dee939b6..6fbcd7c1 100644 --- a/packages/event_source_client/lib/src/sse_client_html.dart +++ b/packages/event_source_client/lib/src/sse_client_html.dart @@ -1,6 +1,6 @@ import 'dart:async'; -// ignore: deprecated_member_use -import 'dart:html' as html; +import 'dart:js_interop'; +import 'package:web/web.dart' as web; import 'dart:math' as math; import '../launchdarkly_event_source_client.dart'; @@ -8,10 +8,10 @@ import '../launchdarkly_event_source_client.dart'; import 'backoff.dart'; import 'message_event.dart' as ld_message_event; -/// An [SSEClient] that uses the [html.EventSource] available on most browsers for web platform support. +/// An [SSEClient] that uses the [web.EventSource] available on most browsers for web platform support. class HtmlSseClient implements SSEClient { /// The underlying eventsource - html.EventSource? _eventSource; + web.EventSource? _eventSource; /// This controller is for the events going to the subscribers of this client. late final StreamController @@ -54,27 +54,29 @@ class HtmlSseClient implements SSEClient { } void _setupConnection() { - _eventSource = html.EventSource(_uri.toString()); + _eventSource = web.EventSource(_uri.toString()); for (var eventType in _eventTypes) { - _eventSource?.addEventListener(eventType, _handleMessageEvent); + _eventSource?.addEventListener(eventType, _handleMessageEvent.toJS); } - _eventSource?.addEventListener('error', _handleError); + _eventSource?.addEventListener('error', _handleError.toJS); } - void _handleError(html.Event event) { + void _handleError(web.Event event) { // The browser event source errors are reasonably opaque, if we could // determine the type of condition, then this is where we would // determine if this was a temporary or permanent failure. restart(); } - void _handleMessageEvent(html.Event event) { + void _handleMessageEvent(web.Event event) { _activeSince = DateTime.now().millisecondsSinceEpoch; - final messageEvent = event as html.MessageEvent; - final ldMessageEvent = ld_message_event.MessageEvent( - messageEvent.type, messageEvent.data, messageEvent.lastEventId); - _messageEventsController.sink.add(ldMessageEvent); + final messageEvent = event as web.MessageEvent; + if (messageEvent.data != null && messageEvent.data.typeofEquals('string')) { + final ldMessageEvent = ld_message_event.MessageEvent(messageEvent.type, + (messageEvent.data as JSString).toDart, messageEvent.lastEventId); + _messageEventsController.sink.add(ldMessageEvent); + } } /// Subscribe to this [stream] to receive events and sometimes errors. The first diff --git a/packages/event_source_client/pubspec.yaml b/packages/event_source_client/pubspec.yaml index a7058f7a..53297442 100644 --- a/packages/event_source_client/pubspec.yaml +++ b/packages/event_source_client/pubspec.yaml @@ -9,6 +9,7 @@ environment: dependencies: http: ^1.1.0 + web: ^1.1.1 dev_dependencies: test: ^1.24.3 diff --git a/packages/flutter_client_sdk/example/.metadata b/packages/flutter_client_sdk/example/.metadata index c0abc0c7..e8f7bf91 100644 --- a/packages/flutter_client_sdk/example/.metadata +++ b/packages/flutter_client_sdk/example/.metadata @@ -4,8 +4,8 @@ # This file should be version controlled and should not be manually edited. version: - revision: "0f7f08d5354856ea41930f2c178a96ca97518d5a" - channel: "master" + revision: "ea121f8859e4b13e47a8f845e4586164519588bc" + channel: "stable" project_type: app @@ -13,26 +13,26 @@ project_type: app migration: platforms: - platform: root - create_revision: 0f7f08d5354856ea41930f2c178a96ca97518d5a - base_revision: 0f7f08d5354856ea41930f2c178a96ca97518d5a + create_revision: ea121f8859e4b13e47a8f845e4586164519588bc + base_revision: ea121f8859e4b13e47a8f845e4586164519588bc - platform: android - create_revision: 0f7f08d5354856ea41930f2c178a96ca97518d5a - base_revision: 0f7f08d5354856ea41930f2c178a96ca97518d5a + create_revision: ea121f8859e4b13e47a8f845e4586164519588bc + base_revision: ea121f8859e4b13e47a8f845e4586164519588bc - platform: ios - create_revision: 0f7f08d5354856ea41930f2c178a96ca97518d5a - base_revision: 0f7f08d5354856ea41930f2c178a96ca97518d5a + create_revision: ea121f8859e4b13e47a8f845e4586164519588bc + base_revision: ea121f8859e4b13e47a8f845e4586164519588bc - platform: linux - create_revision: 0f7f08d5354856ea41930f2c178a96ca97518d5a - base_revision: 0f7f08d5354856ea41930f2c178a96ca97518d5a + create_revision: ea121f8859e4b13e47a8f845e4586164519588bc + base_revision: ea121f8859e4b13e47a8f845e4586164519588bc - platform: macos - create_revision: 0f7f08d5354856ea41930f2c178a96ca97518d5a - base_revision: 0f7f08d5354856ea41930f2c178a96ca97518d5a + create_revision: ea121f8859e4b13e47a8f845e4586164519588bc + base_revision: ea121f8859e4b13e47a8f845e4586164519588bc - platform: web - create_revision: 0f7f08d5354856ea41930f2c178a96ca97518d5a - base_revision: 0f7f08d5354856ea41930f2c178a96ca97518d5a + create_revision: ea121f8859e4b13e47a8f845e4586164519588bc + base_revision: ea121f8859e4b13e47a8f845e4586164519588bc - platform: windows - create_revision: 0f7f08d5354856ea41930f2c178a96ca97518d5a - base_revision: 0f7f08d5354856ea41930f2c178a96ca97518d5a + create_revision: ea121f8859e4b13e47a8f845e4586164519588bc + base_revision: ea121f8859e4b13e47a8f845e4586164519588bc # User provided section diff --git a/packages/flutter_client_sdk/example/web/index.html b/packages/flutter_client_sdk/example/web/index.html index 45cf2ca3..29b58086 100644 --- a/packages/flutter_client_sdk/example/web/index.html +++ b/packages/flutter_client_sdk/example/web/index.html @@ -21,7 +21,7 @@ - + @@ -31,29 +31,8 @@ example - - - - - + diff --git a/packages/flutter_client_sdk/lib/src/config/defaults/flutter_default_config.dart b/packages/flutter_client_sdk/lib/src/config/defaults/flutter_default_config.dart index 15d15d21..615411a7 100644 --- a/packages/flutter_client_sdk/lib/src/config/defaults/flutter_default_config.dart +++ b/packages/flutter_client_sdk/lib/src/config/defaults/flutter_default_config.dart @@ -1,6 +1,6 @@ import 'stub_config.dart' if (dart.library.io) 'io_config.dart' - if (dart.library.html) 'js_config.dart'; + if (dart.library.js_interop) 'js_config.dart'; /// Configuration common to web and mobile is contained in this file. /// diff --git a/packages/flutter_client_sdk/lib/src/flutter_state_detector.dart b/packages/flutter_client_sdk/lib/src/flutter_state_detector.dart index 8b7d62b3..37eb0acd 100644 --- a/packages/flutter_client_sdk/lib/src/flutter_state_detector.dart +++ b/packages/flutter_client_sdk/lib/src/flutter_state_detector.dart @@ -6,7 +6,7 @@ import 'package:flutter/scheduler.dart'; import 'connection_manager.dart'; import 'lifecycle/stub_lifecycle_listener.dart' if (dart.library.io) 'lifecycle/io_lifecycle_listener.dart' - if (dart.library.html) 'lifecycle/js_lifecycle_listener.dart'; + if (dart.library.js_interop) 'lifecycle/js_lifecycle_listener.dart'; /// This class detects the application and network state for flutter. final class FlutterStateDetector implements StateDetector { diff --git a/packages/flutter_client_sdk/lib/src/lifecycle/js_lifecycle_listener.dart b/packages/flutter_client_sdk/lib/src/lifecycle/js_lifecycle_listener.dart index 39733afc..29952ca0 100644 --- a/packages/flutter_client_sdk/lib/src/lifecycle/js_lifecycle_listener.dart +++ b/packages/flutter_client_sdk/lib/src/lifecycle/js_lifecycle_listener.dart @@ -1,6 +1,6 @@ import 'dart:async'; -// ignore: deprecated_member_use -import 'dart:html' as html; +import 'dart:js_interop'; +import 'package:web/web.dart' as web; import 'package:flutter/widgets.dart'; @@ -12,17 +12,17 @@ class LDAppLifecycleListener { LDAppLifecycleListener() { _streamController = StreamController.broadcast(); - void listenerFunc(event) => - _streamController.add(html.document.hidden == true + void listenerFunc(web.Event event) => + _streamController.add(web.document.hidden == true ? AppLifecycleState.hidden : AppLifecycleState.resumed); _streamController.onListen = () { - html.document.addEventListener('visibilitychange', listenerFunc); + web.document.addEventListener('visibilitychange', listenerFunc.toJS); }; _streamController.onCancel = () { - html.document.removeEventListener('visibilitychange', listenerFunc); + web.document.removeEventListener('visibilitychange', listenerFunc.toJS); }; } diff --git a/packages/flutter_client_sdk/pubspec.yaml b/packages/flutter_client_sdk/pubspec.yaml index 7bce1696..3d8ee294 100644 --- a/packages/flutter_client_sdk/pubspec.yaml +++ b/packages/flutter_client_sdk/pubspec.yaml @@ -17,6 +17,7 @@ dependencies: launchdarkly_common_client: 1.4.1 shared_preferences: ^2.2.2 connectivity_plus: ">=5.0.2 <7.0.0" + web: ^1.1.1 dev_dependencies: flutter_test: