Skip to content

✨ Feature Request: Built-in Storage Adapters or Separate Packages #2

@moazelsawaf

Description

@moazelsawaf

Hi @SPiercer πŸ‘‹πŸ»

Thank you for creating this excellent package! I think this enhancement would make it even more convenient to use πŸ™πŸ»

πŸ€” Problem

Currently, users need to manually implement the Storage interface for each backend they want to use. The README shows examples for:

  • SharedPreferences
  • HydratedBloc
  • Hive

While these examples are helpful, every user has to copy-paste and maintain this boilerplate code in their own projects.

// Users must implement this for each storage backend
class SharedPreferencesStorage implements Storage {
  final SharedPreferences _prefs;
  SharedPreferencesStorage(this._prefs);
  
  @override
  dynamic read(String key) {
    final value = _prefs.getString(key);
    if (value == null) return null;
    return jsonDecode(value);
  }
  
  @override
  Future<void> write(String key, dynamic value) async {
    await _prefs.setString(key, jsonEncode(value));
  }
  
  // ... more boilerplate
}

πŸ’‘ Proposed Solution

Provide ready-to-use storage adapters either:

Option 1: Built-in Adapters πŸ”§

Include common adapters directly in the saveable package:

import 'package:saveable/saveable.dart';
import 'package:saveable/adapters.dart'; // Built-in adapters

void main() async {
  final prefs = await SharedPreferences.getInstance();
  final storage = SharedPreferencesStorageAdapter(prefs); // ✨ Ready to use
  
  Saveable.setDefaultStorage(storage);
}

Option 2: Separate Adapter Packages πŸ“¦ (Recommended)

Create separate packages for each storage backend:

Core package:

  • saveable - Core functionality + Storage interface

Adapter packages:

  • saveable_shared_preferences - SharedPreferences adapter
  • saveable_hive - Hive adapter
  • saveable_hydrated_bloc - HydratedBloc adapter
  • etc..
// Clean and simple usage
import 'package:saveable/saveable.dart';
import 'package:saveable_shared_preferences/saveable_shared_preferences.dart';

void main() async {
  final prefs = await SharedPreferences.getInstance();
  final storage = SaveableSharedPreferences(prefs); // ✨ From adapter package
  
  Saveable.setDefaultStorage(storage);
}

You can check dio_cache_interceptor package for more details is it is following this pattern.

🎯 Benefits

  • Less boilerplate πŸ“‰: No need to copy-paste adapter code
  • Tested & maintained βœ…: Official adapters are tested and kept up-to-date
  • Smaller bundle size πŸ“¦: With separate packages, users only include what they need
  • Community contributions 🀝: Easier for community to contribute new adapters
  • Follows best practices πŸ†: Matches patterns from popular packages like dio_cache_interceptor

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions