All Projects → eGust → flutter_cache_store

eGust / flutter_cache_store

Licence: BSD-3-Clause license
More configurable cache manager for Flutter

Programming Languages

dart
5743 projects

Projects that are alternatives of or similar to flutter cache store

flutter-simple-url-preview
Simple url preview package for flutter
Stars: ✭ 30 (+50%)
Mutual labels:  flutter-package
link text
Easy to use text widget for Flutter apps, which converts inlined urls into working, clickable links
Stars: ✭ 20 (+0%)
Mutual labels:  flutter-package
flutter section table view
A iOS like table view including section, row, section header and divider
Stars: ✭ 73 (+265%)
Mutual labels:  flutter-package
Liquid
An advance flutter UI Kit for developing responsive, cross platform applications.
Stars: ✭ 27 (+35%)
Mutual labels:  flutter-package
code editor
A code editor (dart, js, html, ...) for Flutter with syntax highlighting and custom theme.
Stars: ✭ 48 (+140%)
Mutual labels:  flutter-package
flutter google maps
A Flutter plugin for integrating Google Maps in iOS, Android and Web applications. It is a wrapper of google_maps_flutter for Mobile and google_maps for Web.
Stars: ✭ 86 (+330%)
Mutual labels:  flutter-package
fancy bar
A fancy yet beautiful animated widget for your Flutter apps
Stars: ✭ 33 (+65%)
Mutual labels:  flutter-package
liquid button
Liquify your buttons, web demo at website
Stars: ✭ 18 (-10%)
Mutual labels:  flutter-package
research.package
A Flutter package implementing support for surveys like ResearchStack and ResearchKit
Stars: ✭ 43 (+115%)
Mutual labels:  flutter-package
flutter-package-selection menu
A flutter widget, highly customizable, to select an item from a list of items.
Stars: ✭ 32 (+60%)
Mutual labels:  flutter-package
sounds
Flutter plugin for sound. Audio recorder and player.
Stars: ✭ 74 (+270%)
Mutual labels:  flutter-package
date field
Flutter DateField and DateFormField
Stars: ✭ 33 (+65%)
Mutual labels:  flutter-package
wasm.dart
WebAssembly virtual machine for Dart [work in progress]
Stars: ✭ 43 (+115%)
Mutual labels:  flutter-package
simple gesture detector
Easy to use, reliable and lightweight gesture detector for Flutter apps, exposing simple API for basic gestures
Stars: ✭ 26 (+30%)
Mutual labels:  flutter-package
dough
This package provides some widgets you can use to create a smooshy UI.
Stars: ✭ 518 (+2490%)
Mutual labels:  flutter-package
route transitions
A flutter library containing useful animations and friendly functions for routing 🚦
Stars: ✭ 43 (+115%)
Mutual labels:  flutter-package
open route service
An encapsulation made around openrouteservice API for Dart and Flutter projects. Made for easy generation of Routes and Directions on Maps, Isochrones, Time-Distance Matrix, Pelias Geocoding, POIs, Elevation and routing Optimizations using their amazing API.
Stars: ✭ 20 (+0%)
Mutual labels:  flutter-package
FlutterLoadingGIFs
Loading indicator GIFs. Material and Cupertino (Android and iOS) loading indicators in assorted sizes. Use as placeholders for loading remote image assets. Demo: https://gallery.codelessly.com/flutterwebsites/loadinggifs/
Stars: ✭ 28 (+40%)
Mutual labels:  flutter-package
flutter dauth
A flutter package for authentication with DAuth(an OAuth2 based SSO (Single Sign On) for NITT students) authorisations service on behalf of the resource-owner/user.
Stars: ✭ 36 (+80%)
Mutual labels:  flutter-package
Motion-Tab-Bar
A beautiful animated flutter widget package library. The tab bar will attempt to use your current theme out of the box, however you may want to theme it.
Stars: ✭ 237 (+1085%)
Mutual labels:  flutter-package

flutter_cache_store

A flexible cache manager for Flutter.

This package is highly inspired by flutter_cache_manager. Can be easily switched to each other.

Quick Start

import 'package:flutter_cache_store/flutter_cache_store.dart';

void demo(String url) async {
  final store = await CacheStore.getInstance();
  final file = await store.getFile(url);
  // do something with file...
}

APIs

CacheStore

void api() async {
  // get store instance
  CacheStore store = await CacheStore.getInstance(
    namespace: 'unique_name', // default: null - valid filename used as unique id
    policy: LeastFrequentlyUsedPolicy(), // default: null - will use `LessRecentlyUsedPolicy()`
    clearNow: true, // default: false - whether to clean up immediately
    fetch: myFetch, // default: null - a shortcut of `CacheStore.fetch`
  );

  // You can change custom fetch method at anytime.
  // Set it to `null` will simply use `http.get`
  store.fetch = myFetch;

  // fetch a file from an URL and cache it
  File file = await store.getFile(
    'url', // GET method
    key: null, // use custom string instead of URL
    headers: {}, // same as http.get
    fetch: myFetch, // Optional: CustomFunction for making custom request
    // Optional: Map<String, dynamic> any custom you want to pass to your custom fetch function.
    custom: {'method': 'POST', 'body': 'test'},
    flushCache: false, // whether to re-download the file
  );

  // flush specific files by keys
  await store.flush([
    'key', // key (default is the URL) passed to `getFile`
  ]);

  // remove all cached files
  await store.clearAll();
}

// Custom fetch function.
// A demo of how you can achieve a fetch supporting POST with body
Future<Response> myFetch(url,
    {Map<String, String> headers, Map<String, dynamic> custom}) {
  final data = custom ?? {};
  switch (data['method'] ?? '') {
    case 'POST':
      {
        return post(url, headers: headers, body: data['body']);
      }
    default:
      return get(url, headers: headers);
  }
}

Cache File Structure

By default, the cached files will be saved under $TEMP/cache_store. $TEMP is generated by path_provider. The default temp filenames are timestamp-based 11 chars.

You can customize your own file structure under $TEMP/cache_store by overriding Policy. There is an example:

Let's suppose your are developing a reader for novels, and your app will cache chapters of books. Your API returns some IDs of books and chapters, and an ID only contains letters and digits.

// Extends a Policy class and override `generateFilename`
class LRUCachePolicy extends LessRecentlyUsedPolicy {
  LRUCachePolicy({int maxCount}) : super(maxCount: maxCount);

  @override
  String generateFilename({final String key, final String url}) =>
      key; // use key as the filename
}

void customizedCacheFileStructure() async {
  // get store instance
  CacheStore store = await CacheStore.getInstance(
    policy: LRUCachePolicy(maxCount: 4096),
    namespace: 'my_store',
  );

  // fetch a file from an URL and cache it
  String bookId = 'book123';
  String chapterId = 'ch42';
  String chapterUrl = 'https://example.com/book123/ch42';
  File file = await store.getFile(
    chapterUrl,
    key: '$bookId/$chapterId', // use IDs as path and filename
  );

  // Your file will be cached as `$TEMP/cache_store__my_store/book123/ch42`
}

Cache Policy

  • LessRecentlyUsedPolicy

    LRU policy. Less Recently Used files will be removed when reached maxCount. Each time you access a file will update its used timestamp.

    new LessRecentlyUsedPolicy(
      maxCount: 999,
    );
  • LeastFrequentlyUsedPolicy

    LFU policy. Least Frequently Used files will be removed when reached maxCount. Each time you access a file will increase its hit count. After hitAge time the hit will expire. It will fallback to LRU policy if files have same hit count.

    new LeastFrequentlyUsedPolicy(
      maxCount: 999,
      hitAge: Duration(days: 30),
    );
  • CacheControlPolicy

    Cache-Control header policy. This policy generally follows max-age=<seconds> or s-maxage=<seconds> rules of http response header Cache-Control. If the max-age-seconds not been set, it will use minAge unless you set it to null. The age will not be longer than maxAge.

    new CacheControlPolicy(
      maxCount: 999,
      minAge: Duration(seconds: 30), // nullable
      maxAge: Duration(days: 30), // nullable
    );
  • FifoPolicy

    First-In, First-Out policy, super simple and maybe for example only.

    new FifoPolicy(
      maxCount: 999,
    );

Performance Warning

  • The implementation maintains all key-item in memory to improve the speed. So maxCount must between 1 and 100000 (100k) due to the cost of RAM and file system.

  • Currently, all the policies simply sort all items to expire files. It may hit performance due to O(N*logN) complexity.

    Will switch to priority queue which has O(N*logK) while K usually is a very small number.

How to implement your own policy

The interface is a simple abstract class. You only have to implement a few methods.

abstract class CacheStorePolicy {
  // IT'S THE ONLY METHOD YOU HAVE TO IMPLEMENT.
  // `store` will invoke this method from time to time.
  // Make sure return all expired items at once.
  // then `store` will manage to remove the cached files.
  // you also have to save your data if need to persist some data.
  Future<Iterable<CacheItem>> cleanup(Iterable<CacheItem> allItems);

  // will be invoked when store.clearAll called.
  Future<void> clearAll(Iterable<CacheItem> allItems) async {}

  // will invoke only once when the `store` is created and load saved data.
  // you need to load persistent data and restore items' payload.
  // only returned items will be cached. others will be recycled later.
  Future<Iterable<CacheItem>> restore(List<CacheItem> allItems) async => allItems;

  // event when a new `CacheItem` has been added to the cache.
  // you may need to attach a `CacheItemPayload` instance to it.
  Future<void> onAdded(final CacheItem addedItem) async {}

  // event when an item just been accessed.
  // you may need to attach or update item's payload.
  Future<void> onAccessed(final CacheItem accessedItem, bool flushed) async {}

  // event when a request just finished.
  // the response headers will be passed as well.
  Future<void> onDownloaded(final CacheItem item, final Map<String, String> headers) async {}

  // event when `store.flush` has called
  Future<void> onFlushed(final Iterable<CacheItem> flushedItems) async {}

  // filename (including path) relative to `CacheItem.rootPath`.
  // usually ignore this unless need a better files structure.
  // you must provide valid filenames.
  String generateFilename({final String key, final String url}) =>
      Utils.genName(); // timestamp based random filename
}
  • Tips

    You don't have to implement all of the onAdded, onAccessed and onDownloaded.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].