pro_mpack 2.1.0 copy "pro_mpack: ^2.1.0" to clipboard
pro_mpack: ^2.1.0 copied to clipboard

A Dart library for serializing and deserializing data in the MessagePack format.

pro_mpack #

A high-performance Dart library for serializing and deserializing data using the MessagePack format.

MessagePack is an efficient binary serialization format that's smaller and faster than JSON, while maintaining similar flexibility. This library provides a modern, clean implementation of the MessagePack specification with powerful support for custom extension types.

Features #

Unified & Modern API

  • Single entry point through the MessagePack class
  • Support for both Declarative (builder pattern) and Imperative extension registration
  • Full integration with Dart's Codec system (dart:convert)

🚀 High Performance

  • Zero-copy operations where possible
  • Efficient buffer management with BinaryWriterPool
  • Optimized encoding/decoding paths for different value ranges
  • Fast UTF-8 string handling

🔧 Flexible & Extensible

  • Easy custom extension support with recursive packing/unpacking
  • Built-in DateTime timestamp support
  • Float wrapper: Force 32-bit float serialization with Float
  • Groups: Organise multiple related types under a single extension ID (great for polymorphism)
  • Reusable serializer/deserializer engines for low-level control

📦 Production Ready

  • Comprehensive test coverage
  • Cross-platform support (VM, Web, Native)

Quick Start #

Basic Usage #

import 'package:pro_mpack/pro_mpack.dart';

void main() {
  // Create a MessagePack instance
  final mpack = MessagePack();

  final data = {
    'name': 'Alice',
    'age': 30,
    'scores': [95, 87, 92],
  };

  final bytes = mpack.pack(data);
  print('Serialized to ${bytes.length} bytes');

  // Unpack and cast if needed
  final decoded = mpack.unpack<Map>(bytes);
  print(decoded); // {name: Alice, age: 30, ...}
}

Simple Functions #

For quick serialization without creating an instance, use the top-level functions:

import 'package:pro_mpack/pro_mpack.dart';

void main() {
  // Single value serialization/deserialization
  final bytes = serialize({'key': 'value', 'count': 42});
  final decoded = deserialize(bytes);
  print(decoded); // {key: value, count: 42}

  // Multiple values serialized to a single buffer
  final multiBytes = serializeAll([1, 'hello', true, {'nested': true}]);
  final decodedAll = deserializeAll(multiBytes);
  print(decodedAll); // [1, hello, true, {nested: true}]

  // Optional parameters
  final withBuffer = serialize({'data': 'large'}, initialBufferSize: 2048);
  final withMapOrder = deserialize(
    serialize({'z': 1, 'a': 2}),
    preserveMapOrder: true, // preserves insertion order
  );
}

Advanced Usage: Custom Extensions #

Perfect for configuring your application's data protocol in one place.

final mpack = MessagePack(
  extensions: (config) {
    // Register a custom codec for BigInt, which is not natively supported by MessagePack
    config.register<BigInt>(
      extId: 1,
      encoder: (val, ctx) => ctx.pack(val.toString()),
      decoder: (bytes, ctx) => BigInt.parse(ctx.unpack<String>(bytes)),
    );

    // Register a group of related types under a common base class
    config.registerGroup<dynamic>(
      extId: 2,
      builder: (group) {
        group.add<Address>(
          subId: 1,
          encoder: (addr, ctx) => ctx.packAll([addr.street, addr.city]),
          decoder: (data, ctx) {
            final [street as String, city as String] = ctx.unpackAll(data);
            return Address(street: street, city: city);
          },
        );
      },
    );
  },
);

class Address {
  const Address({required this.street, required this.city});
  final String street;
  final String city;
}

2. Imperative Approach #

Useful for dynamic configuration or modular extensions.

final mpack = MessagePack();

mpack.register<MyType>(
  extId: 10,
  encoder: (v, ctx) => myEncoder(v),
  decoder: (d, ctx) => myDecoder(d),
);

3. Sub-registries (Groups) #

MessagePack extension IDs are limited to the range -128 to 127 (256 values total). When you have many related types or polymorphic hierarchies, registering each type separately quickly exhausts this space. registerGroup solves this by letting you group multiple subtypes under a single extension ID — each subtype uses an internal subId to distinguish itself.

This is ideal for:

  • Polymorphic types: A base class with many subclasses (e.g., ShapeCircle, Square, Triangle)
  • Organized type families: Related models that share a namespace (e.g., all User-related types)
  • ID conservation: Reducing the number of extension IDs consumed when you have many small types
mpack.registerGroup<Shape>(
  extId: 20,
  builder: (group) {
    group.add<Circle>(
      subId: 1,
      encoder: (c, ctx) => ctx.pack(c.radius),
      decoder: (d, ctx) => Circle(ctx.unpack(d)),
    );
    group.add<Square>(
      subId: 2,
      encoder: (s, ctx) => ctx.pack(s.side),
      decoder: (d, ctx) => Square(ctx.unpack(d)),
    );
  },
);

4. Float Wrapper #

By default, double values are serialized as 64-bit floats. Use the Float wrapper for 32-bit:

final bytes = mpack.pack(Float(3.14)); // Serialized as float32

Error Handling #

pro_mpack uses a modern sealed exception hierarchy (Dart 3.10+), providing granular control over error handling and actionable suggestions to fix issues.

try {
  final result = deserialize(corruptedBytes);
} on MessagePackException catch (e) {
  // Use pattern matching for exhaustive error handling
  switch (e) {
    case MessagePackFormatException():
      print('Binary data is invalid: ${e.message}');
    case MessagePackUnsupportedTypeException():
      print('No encoder for type: ${e.unsupportedType}');
    case MessagePackSizeException():
      print('Data exceeds 4GB limit: ${e.message}');
    case MessagePackConfigurationException():
      print('Invalid extension setup: ${e.message}');
  }
  
  // Every exception includes a helpful suggestion
  if (e.suggestion != null) {
    print('💡 Suggestion: ${e.suggestion}');
  }
}

Testing #

The library includes comprehensive tests covering all features and edge cases. To run the tests, use:

dart test

License #

MIT License. See LICENSE for details.

3
likes
160
points
1.91k
downloads

Documentation

Documentation
API reference

Publisher

verified publisherpro100.dev

Weekly Downloads

A Dart library for serializing and deserializing data in the MessagePack format.

Repository (GitHub)
View/report issues

Topics

#mpack #msgpack #messagepack #codec #binary

License

MIT (license)

Dependencies

pro_binary

More

Packages that depend on pro_mpack