query_kit 1.0.0 copy "query_kit: ^1.0.0" to clipboard
query_kit: ^1.0.0 copied to clipboard

Dart port of TanStack Query's query-core: caching, background refetching, retries and mutations, no Flutter needed. An AI-coded community port, not affiliated with TanStack.

example/example.dart

// query_kit is an entirely AI-coded project: all code, tests and
// documentation were written by AI coding agents (Anthropic's Claude). A
// human maintainer set the goals and reviews releases, but did not write the
// code.
//
// A pure-Dart tour of the core: one imperative fetch, one observer, a cache
// write, an invalidation, and the cleanup that lets the process exit.
//
//   dart run example/example.dart
import 'dart:async';

import 'package:query_kit/query_kit.dart';

/// A stand-in for an HTTP client.
class TaskApi {
  int calls = 0;

  Future<List<String>> listTasks() async {
    calls++;
    await Future<void>.delayed(const Duration(milliseconds: 20));
    return const ['kitchen', 'hallway', 'garage'];
  }
}

final api = TaskApi();

final tasksKey = QueryKey(<Object?>['tasks']);

Future<List<String>> fetchTasks(QueryFunctionContext context) =>
    api.listTasks();

QueryOptions<List<String>> tasksQuery() => QueryOptions<List<String>>(
      queryKey: tasksKey,
      queryFn: fetchTasks,
      staleTime: const StaleTime.duration(Duration(seconds: 30)),
    );

Future<void> main() async {
  final client = QueryClient();
  // Mounted, the client reacts to focus and connectivity: refetch on focus
  // and reconnect, and paused mutations resume when the network is back. In
  // pure Dart you drive the managers yourself (`client.onlineManager
  // .setOnline(false)` and back); the Flutter binding wires them to the app.
  client.mount();

  // Imperative: fetch, cache, and complete with the data.
  final tasks = await client.query(tasksQuery());
  print('fetched ${tasks.length} tasks (api calls: ${api.calls})');

  // Fresh data is served from the cache: no second call.
  await client.query(tasksQuery());
  print('again from cache (api calls: ${api.calls})');

  // Reactive: an observer reports every change under its key as a sealed
  // result, so the switch is exhaustive and the data needs no `!`.
  final observer = client.observe<List<String>, int>(
    QuerySelectOptions<List<String>, int>(
      queryKey: tasksKey,
      queryFn: fetchTasks,
      staleTime: const StaleTime.duration(Duration(seconds: 30)),
      select: (names) => names.length,
    ),
  );
  void report(QueryResult<int> result) {
    switch (result) {
      case QueryPending():
        print('observer: loading');
      case QuerySuccess(:final data, :final isFetching):
        print('observer: $data tasks${isFetching ? ' (refetching)' : ''}');
      case QueryError(:final error, :final staleData):
        print('observer: $error (still showing $staleData)');
    }
  }

  // Subscribing reports changes from here on; the current result is a read.
  report(observer.currentResult);
  final unsubscribe = observer.subscribe(report);

  // A cache write reaches every observer of that key.
  client.updateQueryData<List<String>>(
    tasksKey,
    (previous) => [...?previous, 'attic'],
  );

  // Invalidating marks the entry stale and refetches it for its observers.
  await client.invalidateQueries(
    filters: QueryFilters(queryKey: tasksKey),
  );
  print('after invalidation (api calls: ${api.calls})');

  // A client owns gcTime timers and, mounted, the manager subscriptions;
  // release both so the program can exit.
  unsubscribe();
  client.unmount();
  client.clear();
}
0
likes
160
points
70
downloads

Documentation

API reference

Publisher

verified publisherdualmeta.io

Weekly Downloads

Dart port of TanStack Query's query-core: caching, background refetching, retries and mutations, no Flutter needed. An AI-coded community port, not affiliated with TanStack.

Repository (GitHub)
View/report issues
Contributing

Topics

#cache #state-management #data-fetching #tanstack-query #async

License

MIT (license)

Dependencies

clock, meta

More

Packages that depend on query_kit