sling_gql_sqflite 1.4.0
sling_gql_sqflite: ^1.4.0 copied to clipboard
Persist sling_gql's normalized cache in SQLite with sqflite: a bounded write-behind copy saved as deltas and loaded before the client starts.
example/sling_gql_sqflite_example.dart
// sling_gql's cache persisted in SQLite: opened before the client exists, so
// the first frame of the second launch paints the previous run's data.
//
// In a real app `Query` / `User` / `slingSchema` below are generated by
// `sling_gql_gen` (which also fills in `hash:`); they are written out here so
// the example stands on its own.
//
// type Query { me: User! }
// type User { id: ID! name: String! }
import 'package:flutter/widgets.dart';
import 'package:sling_gql/sling_gql.dart';
import 'package:sling_gql_sqflite/sling_gql_sqflite.dart';
class Query extends Accessor {
Query(super.recorder, super.selection, super.path);
Query.root(Recorder r) : super(r, r.root, const []);
User? get me => object('me', User.new, keyed: true);
}
class User extends Accessor {
User(super.recorder, super.selection, super.path);
String? get id => scalar<String>('id');
String? get name => scalar<String>('name');
}
const slingSchema = SlingSchema<Query, Accessor>(
query: Query.root,
hash: 'example-1',
);
Future<void> main() async {
// sqflite and the lifecycle flush both need the binding.
WidgetsFlutterBinding.ensureInitialized();
final persistence = await SqflitePersistence.open(
'sling_cache.db', // in sqflite's getDatabasesPath()
schema: slingSchema,
maxAge: const Duration(days: 7), // root fields unused for a week go
maxEntities: 10000,
);
debugPrint('${persistence.loaded}');
final client = SlingClient<Query>(
endpoint: Uri.parse('https://api.example.com/graphql'),
schema: slingSchema,
cache: persistence.cache,
// Restored data has no fetch time, so it counts as stale: shown at once,
// then revalidated. Without maxAge (plain cacheFirst) it would never be
// refetched.
maxAge: const Duration(minutes: 5),
);
runApp(
SlingScope<Query>(
client: client,
child: Directionality(
textDirection: TextDirection.ltr,
child: QueryBuilder<Query>(
builder: (context, q, state) => GestureDetector(
// Logout: empties the cache and the database.
onLongPress: persistence.clear,
child: Text(q.me?.name ?? '…'),
),
),
),
),
);
}