Code Monkey home page Code Monkey logo

cached's People

Contributors

anowakiteo avatar axot017 avatar dependabot[bot] avatar devi88 avatar falynsky avatar grzegorz-kozlowski avatar jakubtiteo avatar jlukas99 avatar kamilraczkaiteo avatar lpusz avatar mateuszfilipek2000 avatar patrykpawlak avatar pawelpiechocinski avatar rsc-88 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

cached's Issues

Create cached_annotation README.md

Create cached_annotation README.md file which will contain following:

  • Information that package contains only annotations and is useless without cached package
  • Link to cached package

Make compatible with analyzer ^6.0.0

Hi. Firstly, thanks for a great library.
I just however discovered that when updating to the latest freezed that this library is not supporting analyzer ^6.0.0. I get:

Because freezed >=2.4.2 depends on analyzer ^6.0.0 and cached 1.6.1 depends on analyzer ^5.2.0, freezed >=2.4.2 is incompatible with cached 1.6.1.
And because no versions of cached match >1.6.1 <2.0.0, freezed >=2.4.2 is incompatible with cached ^1.6.1.

Could you please release a version that can use the latest analyzer?
Thanks

Add ClearCached annotation

Todo:

  • Add ClearCached annotation in cached_annotation package:
    • Class should have one positional string argument which should be name of method for which caches should be cleared
  • Add validation:
    • Validate if method passed as argument exist
    • Validate if there are no multiple methods which ClearCached annotation and the same argument
    • Validate if method is void
    • Validate if method is not async
    • Validate if method has no arguments
  • Generate method body which will remove cache of passed method

Proposition:

@withCache
abstract class Example implements _$Example {
   const factory Example() = _Example;
   ...

   @cached
   String getString() {
      // some logic
      return result;
   }

   @ClearCached('getString')
   void clearStrings();
}

To discuss: Should we allow clear method to have implementation or should we require it to be abstract?

Additional requirements after discussion:

  • Method can have implementation
    • If method is not abstract it can return bool or void
    • If method is not abstract super.method() is called
    • If method is not abstract it can has argument
    • If method is not abstract and returns bool cache is cleared only if super.method() call returns true
    • Non abstract methods can be also async

catch22: abstract class vs mixin class

problem: when i generate stubs from the following code, i'll get a dart error:

@WithCache()
abstract class ChatAvatarUtils implements _$ChatAvatarUtils {
  factory ChatAvatarUtils() = _ChatAvatarUtils;
    @Cached(ttl: 300) // 5m only cause we only use it for our own avatar
    Future<String> toBase64({required String imageId}) async => '';
}

dart error:
The class 'ChatAvatarUtils' can't be used as a mixin because it's neither a mixin class nor a mixin.

however, making it a mixin class and running the generator produces another error:

@WithCache()
mixin class ChatAvatarUtils implements _$ChatAvatarUtils {
  factory ChatAvatarUtils() = _ChatAvatarUtils;
    @Cached(ttl: 300) // 5m only cause we only use it for our own avatar
    Future<String> toBase64({required String imageId}) async => '';
}

code generator error:

[ERROR] Class ChatAvatarUtils need to be abstract
package:u2nite/services/image.service.dart:76:13
   ╷
76 │ mixin class ChatAvatarUtils implements _$ChatAvatarUtils {
   │             ^^^^^^^^^^^^^^^
   ╵

what can i do?

$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.10.0, on macOS 13.3.1 22E772610a darwin-arm64, locale en-US)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0-rc1)
[✓] Xcode - develop for iOS and macOS (Xcode 14.3)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.1)
[✓] VS Code (version 1.78.1)
[✓] Connected device (4 available)
[✓] Network resources

• No issues found!

$ dart --version
Dart SDK version: 3.0.0 (stable) (Thu May 4 01:11:00 2023 -0700) on "macos_arm64"

Add ClearAllCached annotation

Todo:

  • Add ClearAllCached annotation in cached_annotation package
  • Add validation:
    • There should be only one method with this annotation
    • Return type should be void
    • Method shouldn't be async
  • Generate class implementation which will remove data from all cache maps

Usage proposition:

@withCache
abstract class Example implements _$Example {
   const factory Example() = _Example;
   ...

   @clearAllCached
   void clear();
}

To discuss: Should we allow clear method to have implementation or should we require it to be abstract?

Add `@CacheKey()` annotation

Add CacheKey annotation which will allow developers to pass function which will generate cache key (by default hashCode is used as a cache key).

  • Create @CacheKey annotation that will take one param with type String Function(dynamic)
  • Validate if @CacheKey is not used with @Ignore or @ignoreCache annotations
  • Create generation logic that will replace hashKey with result of function passed in @CachedKey annotation
  • Write generation tests
  • Write integration tests
  • Write dart doc for @cacheKey
  • Add section in README.md for @cacheKey

Example usage:

String getListCacheKeys(Iterable<Object> l) {
  return l.map((e) => e.hashCode).join('')
}

@withCache
class Example {
  String doSomething(@CacheKey(getListCacheKeys) List<SomeObject> l) {
    return 'something';
  }
}

To discus:
Maybe we should create also something like @iterableCacheKey which will handle case described in "example usage" as its quite generic.

Add dartdoc comments

Todo:

  • Add dartdoc comments for cache package
    • Add dartdoc comment for cachedBuilder (some like "it's function used by build runner", it's not important, just go get points on pub.dev)
  • Add dartdoc comments for cache_annotation package
    • Add dartdoc comment for WithCache annotation
    • Add dartdoc comment for Cached annotation
    • Add dartdoc comment for IgnoreCache annotation
    • Add dartdoc comment for ClearAllCached annotation (not implemented yet)
    • Add dartdoc comment for ClearCached annotation (not implemented yet)

[Feature]: Allow editing cache

Problem

When creating/updating data on a remote data source developers might want to update the local cache after that.

Desired Solution

In the most basic cases something like this could solve it.

Create:

// foo_repository.dart

  @EditCache
  Future<Foo> createFoo(Foo foo) async {
    await dataSource.create(foo);
    return foo;
  }

leading to

// foo_repository.cached.dart

  @override
  Future<Foo> createFoo(Foo foo) async {
    final result = await super.createFoo(foo);
    _getFooCached["${foo.hashCode}"] = result;
    return result;
  }

Update:

// foo_repository.dart

  Future<Foo> getFoo() async {
    // ...
  }

  @EditCache
  Future<Foo> updateFoo(int a, String b) async {
    await dataSource.update(a, b);
    final foo = getFoo();
    return foo.copyWith(a:a, b:b);
  }

leading to

// foo_repository.cached.dart

  @override
  Future<Foo> updateFoo(int a, String b) async {
    final result = await super.updateFoo(a, b);
    _getFooCached["${foo.hashCode}"] = result;
    return result;
  }

Alternatives Considered

No response

On which platorm do you expect this solution?

All

Use other cache libraries, e.g. `shared_preferences`, `hive`

Thank you so much for providing such great package! I'm using it a lot.

However, in some cases I need to store cache in more persistent place than memory, e.g. shared_preferences or hive.
Also, I think on the second/third/etc application boot using saved cache in shared_preferences is better than making call the API during the initialization.

It seems not possible for now using your package. So, do you have any plans or workarounds to support using not only in-memory cache?

persistentStorage option does not respect type of saved data

Hi, first of all, thanks for a great library.
However, when I am trying to read a cached value from persistent storage, during the first launch of the application, the data returned by the cached functions is of the wrong type.

To reproduce this error, it is crucial that the application is restarted, that is, the cache is retrieved from persistent storage and not from a variable (from a generated .cached.dart file).

Please let me know if you are accepting contributions from third party developers. I would like to fix this bug.

  @Cached(persistentStorage: true)
  Future<List<CarDto>> _getCars({@IgnoreCache(useCacheOnError: true) bool ignoreCache = true, }) async => carApiDataSource.getCars();

Error:

type 'List<dynamic>' is not a subtype of type 'FutureOr<List<CarDto>>'
#0      _CarRepositoryImpl._getCars (package:car_catalog/data/car/repository/car_repostiory_impl.cached.dart:63:18)
<asynchronous suspension>
#1      new TaskEither.tryCatch.<anonymous closure> (package:fpdart/src/task_either.dart:280:30)
<asynchronous suspension>
#2      TaskEither.match.<anonymous closure> (package:fpdart/src/task_either.dart:168:25)
<asynchronous suspension>
#3      CarListCubit.init (package:car_catalog/presentation/page/car_list_page/cubit/car_list_cubit.dart:18:5)
<asynchronous suspension>

Workaround
Please note that the type of return has changed from Future<List<CarDto>> to Future<List<dynamic>>

@Cached(persistentStorage: true)
Future<List<dynamic>> _getCars({@IgnoreCache(useCacheOnError: true) bool ignoreCache = true, }) async => carApiDataSource.getCars();

Cache storage implementation

@injectable
class CacheStorage extends CachedStorage {
  Future<Box<Map<dynamic, dynamic>>> _openBox(String key) => Hive.openBox(key);

  @override
  Future<void> write(String key, Map<dynamic, dynamic> data) async {
    final box = await _openBox(key);
    return box.put(key, data);
  }

  @override
  Future<Map<String, dynamic>> read(String key) async {
    final box = await _openBox(key);
    final Map<dynamic, dynamic> result = box.get(key) ?? {};
    final Map<String, dynamic> convertedValue = result.map((key, v) => MapEntry(key.toString(), v));
    return convertedValue;
  }

  @override
  Future<void> delete(String key) async {
    final box = await _openBox(key);
    return box.delete(key);
  }

  @override
  Future<void> deleteAll() async {
    //todo: implement deleteAll
  }
}

My env:
Flutter (Channel stable, 3.13.4, on macOS 14.0 23A344 darwin-arm64, locale en-PL)
cached_annotation: 1.6.0
build_runner: 2.4.6
cached: 1.6.0

Add `@Ignore()` annotation

Add annotation which will ignore method parameter while generating cache key.
TODO:

  • Add @ignore annotation i cached_annotation package
  • Ignore arguments with @ignore annotations while generating cache key
  • Add generation tests
  • Add integration tests
  • Add new annotation to readme
  • Write dartdoc for @ignore annotation

Cache peek

It would be nice to have a way to peek at a value in the cache. One possible API design is:

@Cached()
Future<Result> getResult(params...) { ... }

@CachePeek(methodName: 'getResult')
Result? getResultCached(params...);

This method returns either the cached result or null if no result is cached.

Add `@StreamedCache(...)` annotation

Add annotation which will allow to get cache of given method as a stream.

Todo:

  • Add @StreamedCache(...) annotation in cached_annotation package. Annotation should take 2 params: name of method which cache should be streamed, flag if last values should be emitted for new listener.
  • Add validation:
    • Given method need to exist
    • Given method need to have the same params (excluding prams with @igonore or @ignoreCache annotations) or no params (in this case last value will be emitted)
    • Method need to have return type of Stream of cached method sync type
  • Add generator
  • Add generation tests
  • Add integration tests
  • Add dartdoc for @StreamedCache annotation
  • Add description of @StreamedCache in README.md

Add a way to prevent caching specific results

It would be useful to have a way inside a cached function to signal that a certain result must not be cached.
In particular we are caching results from a server, which can in some situations return data that is explicitly not allowed to be cached. But this can only be known after the data was loaded, not before issuing the call. Thus ignoreCache can not be used to solve the issue here.

Any thoughts on a nice way to support this? In our case we could for example pass a list of types that must not be cached.

LRU algorithm not implement

When set limit to 1 , the second item will never hit the cache! As show in the generated code, the last item will be removed!

  @Cached(
    syncWrite: true,
    limit: 1,
  )
if (_queryCached.length > 1) {
  _queryCached.remove(_queryCached.entries.last.key);
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.