diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cde237..a3989d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.10.1 + +- Exposed the internal `PocketBase.httpClientFactory` constructor option to allow users to provide their own `http.Client` implementation as workaround + for the realtime events on Flutter Web ([#11](https://github.com/pocketbase/dart-sdk/issues/11)). + + ## 0.10.0 - Added `fields` optional parameter to the crud services to limit the returned API fields (_available with PocketBase v0.16.0_). diff --git a/README.md b/README.md index 0ec3157..7e12711 100644 --- a/README.md +++ b/README.md @@ -477,8 +477,23 @@ PocketBase Dart SDK is built on top of the standard `dart-lang/http` package and - Requests cancellation/abort is not supported yet - [dart-lang/http #424](https://github.com/dart-lang/http/issues/424) - Streamed responses (used by the realtime service) are not supported on the web - [dart-lang/http #595](https://github.com/dart-lang/http/issues/595) -Depending on the users demand, we can implement workarounds for the above limitations, -but it would be better to wait the upstream library to apply the necessary fixes. +One possible workaround for the streamed responses is to provide a 3rd party `http.Client` implementation like [`fetch_client`](https://pub.dev/packages/fetch_client) using the `httpClientFactory` constructor option: + +```dart +import "package:pocketbase/pocketbase.dart"; +import 'package:fetch_client/fetch_client.dart'; +import 'package:flutter/foundation.dart' show kIsWeb; + +void main() { + final pb = PocketBase( + "http://127.0.0.1:8090", + // load the fetch_client only for web, otherwise - fallback to the default http.Client() + httpClientFactory: kIsWeb ? () => FetchClient(mode: RequestMode.cors) : null, + ); + + // ... +} +``` ## Development diff --git a/lib/src/client.dart b/lib/src/client.dart index 0a7d47c..0f896fd 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -7,6 +7,7 @@ import "auth_store.dart"; import "client_exception.dart"; import "dtos/record_model.dart"; import "services/admin_service.dart"; +import "services/backup_service.dart"; import "services/collection_service.dart"; import "services/file_service.dart"; import "services/health_service.dart"; @@ -14,7 +15,6 @@ import "services/log_service.dart"; import "services/realtime_service.dart"; import "services/record_service.dart"; import "services/settings_service.dart"; -import "services/backup_service.dart"; /// The main PocketBase API client. class PocketBase { @@ -58,7 +58,7 @@ class PocketBase { /// The underlying http client that will be used to send the request. /// This is used primarily for the unit tests. - late final http.Client Function() _httpClientFactory; + late final http.Client Function() httpClientFactory; /// Cache of all created RecordService instances. final _recordServices = {}; @@ -71,7 +71,7 @@ class PocketBase { http.Client Function()? httpClientFactory, }) { this.authStore = authStore ?? AuthStore(); - _httpClientFactory = httpClientFactory ?? () => http.Client(); + this.httpClientFactory = httpClientFactory ?? () => http.Client(); admins = AdminService(this); collections = CollectionService(this); @@ -165,7 +165,7 @@ class PocketBase { request.headers["Accept-Language"] = lang; } - final requestClient = _httpClientFactory(); + final requestClient = httpClientFactory(); try { final response = await requestClient.send(request); diff --git a/lib/src/services/realtime_service.dart b/lib/src/services/realtime_service.dart index 6790367..dd7e01c 100644 --- a/lib/src/services/realtime_service.dart +++ b/lib/src/services/realtime_service.dart @@ -177,14 +177,18 @@ class RealtimeService extends BaseService { final url = client.buildUrl("/api/realtime").toString(); - _sse = SseClient(url, onClose: () { - _disconnect(); - - if (!completer.isCompleted) { - completer - .completeError(StateError("failed to establish SSE connection")); - } - }); + _sse = SseClient( + url, + httpClientFactory: client.httpClientFactory, + onClose: () { + _disconnect(); + + if (!completer.isCompleted) { + completer + .completeError(StateError("failed to establish SSE connection")); + } + }, + ); // bind subscriptions listener _sse?.onMessage.listen((msg) { diff --git a/lib/src/services/record_service.dart b/lib/src/services/record_service.dart index b155dce..c7decb2 100644 --- a/lib/src/services/record_service.dart +++ b/lib/src/services/record_service.dart @@ -42,7 +42,6 @@ class RecordService extends BaseCrudService { // Realtime handlers // ----------------------------------------------------------------- - /// /// Subscribe to realtime changes to the specified topic ("*" or record id). /// /// If [topic] is the wildcard "*", then this method will subscribe to diff --git a/pubspec.yaml b/pubspec.yaml index 0072901..cab4624 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: pocketbase description: Multi-platform Dart SDK for PocketBase, an open source realtime backend in 1 file. repository: https://github.com/pocketbase/dart-sdk -version: 0.10.0 +version: 0.10.1 environment: sdk: '>=2.14.0 <3.0.0'