cache_guard 0.0.1 copy "cache_guard: ^0.0.1" to clipboard
cache_guard: ^0.0.1 copied to clipboard

Simple async caching for Flutter. Run once, reuse forever. Prevent duplicate calls, support TTL, force refresh — with zero configuration.

example/example.dart

import 'package:flutter/material.dart';
import 'package:cache_guard/cache_guard.dart';

void main() => runApp(const CacheGuardExample());

class CacheGuardExample extends StatelessWidget {
  const CacheGuardExample({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'cache_guard Example',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorSchemeSeed: Colors.teal,
        useMaterial3: true,
        brightness: Brightness.light,
      ),
      home: const DemoPage(),
    );
  }
}

// ─── Simulated API ──────────────────────────────────────────────────────────

class FakeApi {
  /// Simulates a user fetch with a 2-second delay.
  static Future<Map<String, String>> fetchUser() async {
    await Future.delayed(const Duration(seconds: 2));
    return {
      'name': 'John Doe',
      'email': 'john@example.com',
      'fetchedAt': DateTime.now().toIso8601String(),
    };
  }
}

// ─── Demo Page ──────────────────────────────────────────────────────────────

class DemoPage extends StatefulWidget {
  const DemoPage({super.key});

  @override
  State<DemoPage> createState() => _DemoPageState();
}

class _DemoPageState extends State<DemoPage> {
  bool _isLoading = false;
  String? _result;
  int _fetchCount = 0;

  // ── Example 1: Basic cacheGuard() ──────────────────────────────────────

  Future<void> _fetchWithCache() async {
    setState(() {
      _isLoading = true;
      _result = null;
    });

    final user = await cacheGuard<Map<String, String>>(
      'user',
      () async {
        _fetchCount++;
        return FakeApi.fetchUser();
      },
    );

    if (mounted) {
      setState(() {
        _isLoading = false;
        _result = 'Name: ${user['name']}\n'
            'Email: ${user['email']}\n'
            'Fetched at: ${user['fetchedAt']}\n'
            'API calls made: $_fetchCount';
      });
    }
  }

  // ── Example 2: With TTL ────────────────────────────────────────────────

  Future<void> _fetchWithTtl() async {
    setState(() {
      _isLoading = true;
      _result = null;
    });

    final user = await cacheGuard<Map<String, String>>(
      'user_ttl',
      () async {
        _fetchCount++;
        return FakeApi.fetchUser();
      },
      ttl: const Duration(seconds: 10),
    );

    if (mounted) {
      setState(() {
        _isLoading = false;
        _result = 'TTL: 10 seconds\n'
            'Name: ${user['name']}\n'
            'Fetched at: ${user['fetchedAt']}\n'
            'API calls made: $_fetchCount';
      });
    }
  }

  // ── Example 3: Force refresh ───────────────────────────────────────────

  Future<void> _fetchForceRefresh() async {
    setState(() {
      _isLoading = true;
      _result = null;
    });

    final user = await cacheGuard<Map<String, String>>(
      'user',
      () async {
        _fetchCount++;
        return FakeApi.fetchUser();
      },
      forceRefresh: true,
    );

    if (mounted) {
      setState(() {
        _isLoading = false;
        _result = 'Force refreshed!\n'
            'Name: ${user['name']}\n'
            'Fetched at: ${user['fetchedAt']}\n'
            'API calls made: $_fetchCount';
      });
    }
  }

  // ── Example 4: Extension syntax ────────────────────────────────────────

  Future<void> _fetchWithExtension() async {
    setState(() {
      _isLoading = true;
      _result = null;
    });

    _fetchCount++;
    final user = await FakeApi.fetchUser().cache('user_ext');

    if (mounted) {
      setState(() {
        _isLoading = false;
        _result = 'Extension .cache()\n'
            'Name: ${user['name']}\n'
            'Fetched at: ${user['fetchedAt']}\n'
            'API calls made: $_fetchCount';
      });
    }
  }

  // ── Clear all ──────────────────────────────────────────────────────────

  void _clearAll() {
    clearCache();
    _fetchCount = 0;
    setState(() => _result = 'All cache cleared!');
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);

    return Scaffold(
      appBar: AppBar(title: const Text('cache_guard Example')),
      body: SingleChildScrollView(
        padding: const EdgeInsets.all(24),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            // ── Cache status ─────────────────────────────────────────
            Card(
              child: Padding(
                padding: const EdgeInsets.all(16),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text('Cache Status', style: theme.textTheme.titleMedium),
                    const SizedBox(height: 8),
                    Text('hasCache("user"): ${hasCache('user')}'),
                    Text('hasCache("user_ttl"): ${hasCache('user_ttl')}'),
                    Text('hasCache("user_ext"): ${hasCache('user_ext')}'),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 16),

            // ── Basic cacheGuard ─────────────────────────────────────
            ElevatedButton(
              onPressed: _isLoading ? null : _fetchWithCache,
              child: _isLoading
                  ? const SizedBox(
                      width: 20,
                      height: 20,
                      child: CircularProgressIndicator(strokeWidth: 2),
                    )
                  : const Text('Fetch User (cached)'),
            ),
            const SizedBox(height: 12),

            // ── With TTL ─────────────────────────────────────────────
            ElevatedButton.icon(
              onPressed: _isLoading ? null : _fetchWithTtl,
              icon: const Icon(Icons.timer),
              label: const Text('Fetch with TTL (10s)'),
            ),
            const SizedBox(height: 12),

            // ── Force refresh ────────────────────────────────────────
            ElevatedButton.icon(
              onPressed: _isLoading ? null : _fetchForceRefresh,
              icon: const Icon(Icons.refresh),
              label: const Text('Force Refresh'),
            ),
            const SizedBox(height: 12),

            // ── Extension syntax ─────────────────────────────────────
            ElevatedButton.icon(
              onPressed: _isLoading ? null : _fetchWithExtension,
              icon: const Icon(Icons.extension),
              label: const Text('Fetch with .cache() extension'),
            ),
            const SizedBox(height: 12),

            // ── Clear ────────────────────────────────────────────────
            const Divider(),
            OutlinedButton.icon(
              onPressed: _clearAll,
              icon: const Icon(Icons.delete_outline),
              label: const Text('Clear All Cache'),
            ),
            const SizedBox(height: 24),

            // ── Result display ───────────────────────────────────────
            if (_result != null)
              Card(
                color: _result!.contains('cleared')
                    ? Colors.orange.shade50
                    : Colors.green.shade50,
                child: Padding(
                  padding: const EdgeInsets.all(16),
                  child: Text(
                    _result!,
                    style: TextStyle(
                      color: _result!.contains('cleared')
                          ? Colors.orange.shade800
                          : Colors.green.shade800,
                    ),
                  ),
                ),
              ),
          ],
        ),
      ),
    );
  }
}
4
likes
160
points
34
downloads

Documentation

Documentation
API reference

Publisher

verified publisherridltech.my.id

Weekly Downloads

Simple async caching for Flutter. Run once, reuse forever. Prevent duplicate calls, support TTL, force refresh — with zero configuration.

Repository (GitHub)
View/report issues

Topics

#cache #async #caching #ttl #state-management

Funding

Consider supporting this project:

sociabuzz.com

License

MIT (license)

Dependencies

flutter

More

Packages that depend on cache_guard