dartpub.dev DartNative · beta
plugins / senzer_mmkv_generator
se

senzer_mmkv_generator

v1.0.2 MIT

Analyzer-based source generator for senzer_mmkv typed binary codecs.

senzer_mmkv_generator is an analyzer-based source generator for senzer_mmkv that creates strongly typed binary codecs for Dart models, enums, and collections. It focuses on zero-allocation decoding from native buffers while supporting schema evolution through stable field IDs, safe field renames, defaults, and nullable additions. It also provides watch mode for automatic regeneration during development and generates both codec registration code and a deterministic schema history file.

by pigeonmal/senzer_mmkv_generator · DartNative ≥ 3.0 · updated today
Install
Free
pubspec.yaml
dependencies:
  senzer_mmkv_generator:
    hosted: https://dartpub.dev
    version: ^1.0.2
Weekly installs
0
Active apps
0
Rating
0.0 · 0
Open issues
0

senzer_mmkv_generator

Analyzer-based source generator for senzer_mmkv typed binary codecs.

  • Zero-Allocation Decoding: Decodes directly from borrowed native buffers.
  • Schema Evolution: Stable numeric field IDs, safe renames, and backward compatibility.
  • Enums & Collections: Full support for enums, lists, and maps of nested models.
  • Watch Mode: Instant regeneration on save during development with hot reload.

Installation

Add as a development dependency:

dev_dependencies:
  senzer_mmkv_generator: ^1.0.2

Usage

Run once

dart run senzer_mmkv_generator:mmkv_generate .

Watch mode (Recommended during development)

Keep the generator running in the background. It watches your files, debounces rapid edits, and regenerates on save:

dart run senzer_mmkv_generator:mmkv_generate --watch

The generator produces:

  • lib/mmkv_codecs.g.dart: Generated codecs and registerMMKVGeneratedCodecs().
  • lib/mmkv_schema.txt: Deterministic schema history tracking field IDs. Commit both files to Git.

Defining Models

Models must be final classes with final public fields and a single const unnamed constructor using this.field formals:

import 'package:senzer_mmkv/senzer_mmkv.dart';

@MMKVModel()
final class Address {
  const Address({required this.city, required this.country});
  final String city;
  final String country;
}

@MMKVModel()
final class UserProfile {
  const UserProfile({
    required this.id,
    required this.name,
    this.email,
    this.tags = const [],
    this.address,
  });

  final int id;
  final String name;
  final String? email;
  final List<String> tags;
  final Address? address;
}

Supported Types

  • Primitives & Scalars: bool, int, double, String, Uint8List, DateTime, Duration, Uri, BigInt
  • Enums (annotated or referenced)
  • Generated @MMKVModel classes
  • Nullable variations (T?)
  • Typed collections: List<T>, Set<T>, Map<K, V>

Enums

Enums are supported either directly with @MMKVModel() or by referencing any public enum in your models:

@MMKVModel()
enum UserStatus { active, pending, suspended }

Enums serialize as compact varints using their .index without heap allocations.


Schema Evolution & @MMKVField

Renaming fields without losing data

When renaming a variable in Dart, use @MMKVField(from: 'oldName'). The generator transfers the previous schema ID to the new field name so existing stored records decode seamlessly:

@MMKVModel()
final class UserProfile {
  const UserProfile({
    required this.displayName,
  });

  // Preserves existing data stored under 'name':
  @MMKVField(from: 'name')
  final String displayName;
}

Explicit numeric IDs

If you prefer explicit protobuf-style field IDs:

@MMKVModel()
final class UserProfile {
  const UserProfile({
    required this.id,
    this.bio,
  });

  @MMKVField(id: 1)
  final int id;

  @MMKVField(id: 2)
  final String? bio;
}

Adding new fields safely

When adding fields to models already used in production:

  • Make it nullable (final String? bio;) — older stored records without this field decode as null.
  • Or provide a default value (this.role = 'user';) — older stored records decode using the default value.

Runtime Registration

Call registerMMKVGeneratedCodecs() once at app launch before reading or writing typed models:

import 'package:senzer_mmkv/senzer_mmkv.dart';
import 'mmkv_codecs.g.dart';

void main() {
  registerMMKVGeneratedCodecs();

  final storage = createMMKV(id: 'data');
  storage.setObject<UserProfile>('user', user);
}

[!NOTE] Codec registration is idempotent and safe across Flutter / DartNative hot reloads.