diff --git a/ferry/lib/ferry.dart b/ferry/lib/ferry.dart index d12e9fcb..39e7b861 100644 --- a/ferry/lib/ferry.dart +++ b/ferry/lib/ferry.dart @@ -34,7 +34,11 @@ class Client extends TypedLink { this.updateCacheHandlers = const {}, this.defaultFetchPolicies = const {}, this.addTypename = true, - }) : cache = cache ?? Cache(), + }) : cache = cache ?? + Cache( + typePolicies: typePolicies, + addTypename: addTypename, + ), requestController = requestController ?? StreamController.broadcast() { _typedLink = TypedLink.from([ RequestControllerTypedLink(this.requestController), diff --git a/ferry/lib/typed_links.dart b/ferry/lib/typed_links.dart index 31f0ff04..ce686560 100644 --- a/ferry/lib/typed_links.dart +++ b/ferry/lib/typed_links.dart @@ -2,7 +2,6 @@ export 'package:ferry/src/add_typename_typed_link.dart'; export 'package:ferry/src/cache_typed_link.dart'; export 'package:ferry/src/fetch_policy_typed_link.dart'; export 'package:ferry/src/gql_typed_link.dart'; -export 'package:ferry/src/offline_mutation_typed_link.dart'; export 'package:ferry/src/optimistic_typed_link.dart'; export 'package:ferry/src/request_controller_typed_link.dart'; export 'package:ferry/src/update_cache_typed_link.dart'; diff --git a/ferry/pubspec.yaml b/ferry/pubspec.yaml index 9bd36172..bd1d1858 100644 --- a/ferry/pubspec.yaml +++ b/ferry/pubspec.yaml @@ -12,7 +12,6 @@ dependencies: gql_exec: ^0.2.4 meta: ^1.1.8 collection: ^1.14.12 - hive: ^1.4.4 built_value: ^7.1.0 ferry_exec: ^0.0.2 normalize: ^0.4.5 diff --git a/ferry_offline_client/.gitignore b/ferry_offline_client/.gitignore new file mode 100644 index 00000000..925d62ef --- /dev/null +++ b/ferry_offline_client/.gitignore @@ -0,0 +1,11 @@ +# Dart +.dart_tool +.packages +pubspec.lock + +# Documentation +doc/api + +build/ + +test/__hive_data__ diff --git a/ferry_offline_client/CHANGELOG.md b/ferry_offline_client/CHANGELOG.md new file mode 100644 index 00000000..1608a94a --- /dev/null +++ b/ferry_offline_client/CHANGELOG.md @@ -0,0 +1,13 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [0.0.1] + +- initial commit + diff --git a/ferry_offline_client/LICENSE b/ferry_offline_client/LICENSE new file mode 100644 index 00000000..f0f701a1 --- /dev/null +++ b/ferry_offline_client/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2020 Sat Mandir Khalsa + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/ferry_offline_client/README.md b/ferry_offline_client/README.md new file mode 100644 index 00000000..1dc56a05 --- /dev/null +++ b/ferry_offline_client/README.md @@ -0,0 +1,23 @@ +[![MIT License][license-badge]][license-link] +[![PRs Welcome][prs-badge]][prs-link] +[![Watch on GitHub][github-watch-badge]][github-watch-link] +[![Star on GitHub][github-star-badge]][github-star-link] +[![Watch on GitHub][github-forks-badge]][github-forks-link] +[![Discord][discord-badge]][discord-link] + +[license-badge]: https://img.shields.io/github/license/gql-dart/ferry.svg?style=for-the-badge +[license-link]: https://github.com/gql-dart/ferry/blob/master/LICENSE +[prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=for-the-badge +[prs-link]: https://github.com/gql-dart/ferry/issues + +[github-watch-badge]: https://img.shields.io/github/watchers/gql-dart/ferry.svg?style=for-the-badge&logo=github&logoColor=ffffff +[github-watch-link]: https://github.com/gql-dart/ferry/watchers +[github-star-badge]: https://img.shields.io/github/stars/gql-dart/ferry.svg?style=for-the-badge&logo=github&logoColor=ffffff +[github-star-link]: https://github.com/gql-dart/ferry/stargazers +[github-forks-badge]: https://img.shields.io/github/forks/gql-dart/ferry.svg?style=for-the-badge&logo=github&logoColor=ffffff +[github-forks-link]: https://github.com/gql-dart/ferry/network/members + +[discord-badge]: https://img.shields.io/discord/559455668810153989.svg?style=for-the-badge&logo=discord&logoColor=ffffff +[discord-link]: https://discord.gg/QRTfXE + +An offline-ready `ferry` GraphQL Client. \ No newline at end of file diff --git a/ferry_offline_client/analysis_options.yaml b/ferry_offline_client/analysis_options.yaml new file mode 100644 index 00000000..108d1058 --- /dev/null +++ b/ferry_offline_client/analysis_options.yaml @@ -0,0 +1 @@ +include: package:pedantic/analysis_options.yaml diff --git a/ferry_offline_client/lib/ferry_offline_client.dart b/ferry_offline_client/lib/ferry_offline_client.dart new file mode 100644 index 00000000..e90362f7 --- /dev/null +++ b/ferry_offline_client/lib/ferry_offline_client.dart @@ -0,0 +1,117 @@ +import 'dart:async'; +import 'package:meta/meta.dart'; +import 'package:ferry_exec/ferry_exec.dart'; +import 'package:gql/ast.dart'; +import 'package:built_value/serializer.dart'; +import 'package:hive_flutter/hive_flutter.dart'; +import 'package:hive/hive.dart'; +import 'package:ferry/typed_links.dart'; +export 'package:ferry_cache/ferry_cache.dart'; +export 'package:gql_link/gql_link.dart'; +export 'package:normalize/policies.dart'; +export 'package:ferry/src/update_cache_typed_link.dart' show UpdateCacheHandler; +export 'package:ferry_exec/ferry_exec.dart'; +export 'package:gql/ast.dart' show OperationType; +import 'package:ferry_hive_store/ferry_hive_store.dart'; + +import './src/offline_mutation_typed_link.dart'; + +class OfflineClientConfig { + final LinkExceptionHandler linkExceptionHandler; + + OfflineClientConfig({ + this.linkExceptionHandler, + }); +} + +class OfflineClient extends TypedLink { + final Link link; + final StreamController requestController; + final Map typePolicies; + final Map updateCacheHandlers; + final Map defaultFetchPolicies; + final bool addTypename; + final Box storeBox; + final Box mutationQueueBox; + final Cache cache; + final OfflineClientConfig offlineConfig; + final Serializers serializers; + + TypedLink _typedLink; + + OfflineClient({ + @required this.link, + @required this.storeBox, + @required this.mutationQueueBox, + @required this.serializers, + this.offlineConfig, + StreamController requestController, + this.typePolicies = const {}, + this.updateCacheHandlers = const {}, + this.defaultFetchPolicies = const {}, + this.addTypename = true, + }) : cache = Cache( + store: HiveStore(storeBox), + typePolicies: typePolicies, + addTypename: addTypename, + ), + requestController = requestController ?? StreamController.broadcast() { + _typedLink = TypedLink.from([ + RequestControllerTypedLink(this.requestController), + OfflineMutationTypedLink( + cache: cache, + mutationQueueBox: mutationQueueBox, + serializers: serializers, + requestController: this.requestController, + linkExceptionHandler: offlineConfig?.linkExceptionHandler, + ), + if (addTypename) AddTypenameTypedLink(), + if (updateCacheHandlers.isNotEmpty) + UpdateCacheTypedLink( + cache: cache, + updateCacheHandlers: updateCacheHandlers, + ), + FetchPolicyTypedLink( + link: link, + cache: cache, + defaultFetchPolicies: defaultFetchPolicies, + ) + ]); + } + + @override + Stream> request( + OperationRequest request, [ + forward, + ]) => + _typedLink.request(request, forward); + + /// Initializes an [OfflineClient] with default hive boxes + static Future init({ + @required Link link, + @required Serializers serializers, + OfflineClientConfig offlineConfig, + StreamController requestController, + Map typePolicies, + Map updateCacheHandlers, + Map defaultFetchPolicies, + bool addTypename, + }) async { + await Hive.initFlutter(); + final storeBox = await Hive.openBox>('ferry_store'); + final mutationQueueBox = + await Hive.openBox>('ferry_mutation_queue'); + return OfflineClient( + link: link, + storeBox: storeBox, + mutationQueueBox: mutationQueueBox, + serializers: serializers, + offlineConfig: offlineConfig, + requestController: requestController, + typePolicies: typePolicies, + updateCacheHandlers: updateCacheHandlers, + defaultFetchPolicies: defaultFetchPolicies, + addTypename: addTypename, + ); + } +} diff --git a/ferry/lib/src/offline_mutation_typed_link.dart b/ferry_offline_client/lib/src/offline_mutation_typed_link.dart similarity index 100% rename from ferry/lib/src/offline_mutation_typed_link.dart rename to ferry_offline_client/lib/src/offline_mutation_typed_link.dart diff --git a/ferry_offline_client/pubspec.yaml b/ferry_offline_client/pubspec.yaml new file mode 100644 index 00000000..a7837802 --- /dev/null +++ b/ferry_offline_client/pubspec.yaml @@ -0,0 +1,22 @@ +name: ferry_offline_client +version: 0.0.1 +homepage: https://ferrygraphql.com/ +description: An offline-ready Ferry GraphQL Client +repository: https://github.com/gql-dart/ferry +environment: + sdk: '>=2.10.0 <3.0.0' +dependencies: + gql_link: ^0.3.0 + meta: ^1.1.8 + hive: ^1.4.4 + hive_flutter: ^0.3.0+2 + ferry_exec: ^0.0.2 + ferry_cache: ^0.4.2 + ferry_hive_store: ^0.3.2 + ferry: ^0.9.2 + flutter: + sdk: flutter +dev_dependencies: + test: ^1.9.4 + pedantic: ^1.9.0 + ferry_test_graphql: ^0.0.2 diff --git a/ferry/test/typed_links/offline_mutation_typed_link_test.dart b/ferry_offline_client/test/offline_mutation_typed_link_test.dart similarity index 97% rename from ferry/test/typed_links/offline_mutation_typed_link_test.dart rename to ferry_offline_client/test/offline_mutation_typed_link_test.dart index b90884d7..bd87e6c6 100644 --- a/ferry/test/typed_links/offline_mutation_typed_link_test.dart +++ b/ferry_offline_client/test/offline_mutation_typed_link_test.dart @@ -5,7 +5,7 @@ import 'package:rxdart/rxdart.dart'; import 'package:ferry_exec/ferry_exec.dart'; import 'package:async/async.dart'; -import 'package:ferry/src/offline_mutation_typed_link.dart'; +import 'package:ferry_offline_client/src/offline_mutation_typed_link.dart'; import 'package:ferry_test_graphql/schema/serializers.gql.dart'; import 'package:ferry_test_graphql/mutations/variables/create_review.req.gql.dart';