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

The ultimate Flutter/Dart storage solution. Zero external dependencies. Blazing-fast key-value store + full SQL-like query engine + reactive streams + optional AES-256 encryption. Replaces GetStorage, [...]

example/lib/main.dart

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

/// Full example demonstrating VexStorage features.
///
/// Run with: flutter run -d <device> example/lib/main.dart
void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // 1️⃣  Initialise — provide your app's documents directory.
  //     For a real app: `(await getApplicationDocumentsDirectory()).path`
  await Vex.init(
    options: const VexOptions(
      inMemory: true, // ← use inMemory: false + directory for persistence
      // cipher: VexCipher.fromPassword('my-secret-password'), // optional AES-256
    ),
  );

  runApp(const VexExampleApp());
}

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

  @override
  Widget build(BuildContext context) => MaterialApp(
        title: 'VexStorage Example',
        theme: ThemeData(
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
          useMaterial3: true,
        ),
        home: const VexHomePage(),
      );
}

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

  @override
  State<VexHomePage> createState() => _VexHomePageState();
}

class _VexHomePageState extends State<VexHomePage> {
  late VexCollection _users;
  List<VexDocument> _docs = [];
  String _log = '';
  bool _ready = false;

  @override
  void initState() {
    super.initState();
    _setup();
  }

  Future<void> _setup() async {
    _users = await Vex.collection('users');
    _users.createIndex('age');
    // Reactive: rebuild UI on any change.
    _users.watch().listen((_) => _refresh());
    setState(() => _ready = true);
  }

  void _refresh() {
    setState(() {
      _docs = _users.query().sortBy('name').findAll() as List<VexDocument>;
    });
  }

  void _addLog(String msg) => setState(() => _log = msg);

  // ── Demo actions ────────────────────────────────────────────────────────────

  Future<void> _seedData() async {
    await _users.putMany([
      {'name': 'Alice', 'age': 30, 'city': 'London', 'role': 'admin'},
      {'name': 'Bob', 'age': 25, 'city': 'Paris', 'role': 'user'},
      {'name': 'Charlie', 'age': 35, 'city': 'London', 'role': 'admin'},
      {'name': 'Diana', 'age': 28, 'city': 'Berlin', 'role': 'user'},
      {'name': 'Eve', 'age': 22, 'city': 'London', 'role': 'user'},
    ]);
    _addLog('Seeded 5 users');
  }

  Future<void> _queryLondon() async {
    final r = _users
        .query()
        .where('city').eq('London')
        .sortBy('age')
        .findAll() as List<VexDocument>;
    _addLog('London users (${r.length}): ${r.map((d) => d.get<String>('name')).join(', ')}');
  }

  Future<void> _queryAdultsInLondon() async {
    final r = _users
        .query()
        .where('city').eq('London')
        .and('age').gte(28)
        .sortByDesc('age')
        .findAll() as List<VexDocument>;
    _addLog(
        'London adults ≥28 (${r.length}): ${r.map((d) => '${d.get<String>('name')}(${d.get<int>('age')})').join(', ')}');
  }

  Future<void> _aggregation() async {
    final avg = _users.avgOf('age');
    final max = _users.maxOf('age');
    final groups = _users.groupBy('city');
    _addLog(
        'Avg age: ${avg?.toStringAsFixed(1)}, Max: $max, Cities: ${groups.keys.join(', ')}');
  }

  Future<void> _keyValueDemo() async {
    final prefs = await Vex.collection('prefs');
    await prefs.write('theme', 'dark');
    await prefs.write('fontSize', 16);
    final theme = prefs.read<String>('theme');
    final size = prefs.read<int>('fontSize');
    _addLog('Prefs → theme: $theme, fontSize: $size');
  }

  Future<void> _clearAll() async {
    await _users.clear();
    _addLog('Cleared all users');
  }

  @override
  Widget build(BuildContext context) {
    if (!_ready) {
      return const Scaffold(body: Center(child: CircularProgressIndicator()));
    }
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: const Text('⚡ VexStorage Demo'),
      ),
      body: Column(
        children: [
          // ── Action buttons ────────────────────────────────────────────────
          Wrap(
            spacing: 8,
            runSpacing: 4,
            children: [
              _Btn('Seed data', _seedData),
              _Btn('Query London', _queryLondon),
              _Btn('Adults in London', _queryAdultsInLondon),
              _Btn('Aggregation', _aggregation),
              _Btn('Key-Value demo', _keyValueDemo),
              _Btn('Clear', _clearAll, color: Colors.red),
            ],
          ),
          // ── Log ───────────────────────────────────────────────────────────
          if (_log.isNotEmpty)
            Container(
              width: double.infinity,
              margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
              padding: const EdgeInsets.all(10),
              decoration: BoxDecoration(
                color: Colors.deepPurple.shade50,
                borderRadius: BorderRadius.circular(8),
              ),
              child: Text(_log,
                  style: const TextStyle(fontFamily: 'monospace', fontSize: 12)),
            ),
          const Divider(),
          // ── Document list ─────────────────────────────────────────────────
          Expanded(
            child: _docs.isEmpty
                ? const Center(
                    child: Text('No users yet — tap "Seed data"',
                        style: TextStyle(color: Colors.grey)))
                : ListView.builder(
                    itemCount: _docs.length,
                    itemBuilder: (ctx, i) {
                      final doc = _docs[i];
                      return ListTile(
                        leading: CircleAvatar(
                          backgroundColor: doc.get<String>('role') == 'admin'
                              ? Colors.deepPurple
                              : Colors.teal,
                          child: Text(
                              doc.get<String>('name')?.substring(0, 1) ?? '?',
                              style:
                                  const TextStyle(color: Colors.white)),
                        ),
                        title: Text(doc.get<String>('name') ?? ''),
                        subtitle: Text(
                            '${doc.get<String>('city')} · age ${doc.get<int>('age')}'),
                        trailing: Chip(
                          label: Text(doc.get<String>('role') ?? ''),
                          backgroundColor:
                              doc.get<String>('role') == 'admin'
                                  ? Colors.deepPurple.shade100
                                  : Colors.teal.shade100,
                        ),
                        onLongPress: () => _users.delete(doc.id),
                      );
                    },
                  ),
          ),
        ],
      ),
    );
  }
}

class _Btn extends StatelessWidget {
  final String label;
  final VoidCallback onTap;
  final Color? color;

  const _Btn(this.label, this.onTap, {this.color});

  @override
  Widget build(BuildContext context) => ElevatedButton(
        style: ElevatedButton.styleFrom(
            backgroundColor: color, foregroundColor: Colors.white),
        onPressed: onTap,
        child: Text(label),
      );
}
1
likes
150
points
11
downloads

Documentation

Documentation
API reference

Publisher

verified publishermysteriouscoder.com

Weekly Downloads

The ultimate Flutter/Dart storage solution. Zero external dependencies. Blazing-fast key-value store + full SQL-like query engine + reactive streams + optional AES-256 encryption. Replaces GetStorage, Hive, and sqflite in one package.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter

More

Packages that depend on vex_storage