offline_outbox 1.1.2 copy "offline_outbox: ^1.1.2" to clipboard
offline_outbox: ^1.1.2 copied to clipboard

Resilient offline-first outbox and retry queue for Dart and Flutter with disk persistence, exponential backoff, priority scheduling, and deduplication.

offline_outbox #

Pub Version Pub Points Pub Likes CI License


⚑ Why offline_outbox? #

In mobile development, network connections flicker constantly. Standard in-memory retry libraries fail when the app process is terminated or the phone restarts.

offline_outbox provides the Transactional Outbox Pattern for Flutter:

  1. Never Lose a Mutation: When the user places an order, sends a message, or likes a post, the request is written to persistent disk storage before network delivery.
  2. Exponential Backoff with Random Jitter: Failed network requests automatically back off exponentially with randomized jitter to prevent server thundering-herd spikes on reconnect.
  3. Idempotency & Deduplication: Prevents duplicate charges or double orders by checking unique idempotencyKey values before enqueueing.
  4. 4-Tier Priority Scheduling: OutboxPriority.critical requests (payments, bookings) are drained before OutboxPriority.low requests (analytics, logs).
  5. Storage & HTTP Agnostic: Works seamlessly with Dio, package:http, Hive, SQLite, or the built-in FileJsonOutboxStorage.

πŸ“¦ Installation #

Add offline_outbox to your pubspec.yaml:

dependencies:
  offline_outbox: ^1.1.1

Or run:

flutter pub add offline_outbox

πŸš€ Quick Start #

1. Initialize Engine #

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:offline_outbox/offline_outbox.dart';

// Create storage (File-based, Hive, or InMemory)
final storage = FileJsonOutboxStorage(File('/path/to/outbox.json'));

final outbox = OfflineOutboxEngine(
  storage: storage,
  retryPolicy: const RetryPolicy(
    maxAttempts: 5,
    initialDelay: Duration(seconds: 2),
    maxDelay: Duration(minutes: 2),
    backoffMultiplier: 2.0,
    enableJitter: true,
  ),
  executor: (request) async {
    // Perform your actual HTTP / Dio request here:
    // final response = await dio.request(request.endpoint, data: request.payload, ...);
    // return response.statusCode == 200;
    return true; // Return true on success, false/throw on retryable error
  },
);

await outbox.init();

2. Enqueue an Offline Request #

await outbox.enqueue(
  OutboxRequest(
    id: 'req_${DateTime.now().millisecondsSinceEpoch}',
    endpoint: '/api/v1/orders',
    method: 'POST',
    payload: {'item_id': 101, 'quantity': 2},
    priority: OutboxPriority.critical,
    idempotencyKey: 'order_uuid_987654',
  ),
);

3. Process & Drain Queue #

// Drain the queue manually (e.g. on connectivity reconnect):
final int deliveredCount = await outbox.processQueue();

// Or enable background periodic auto-sync:
outbox.startAutoSync(interval: const Duration(seconds: 15));

4. Real-time Status Stream #

// Listen to live pending items count:
outbox.pendingCountStream.listen((count) {
  print('Pending outbox items: $count');
});

// Listen to delivered requests:
outbox.onCompletedStream.listen((req) {
  print('Delivered: ${req.endpoint}');
});

πŸ› οΈ API Reference #

OutboxRequest Parameters #

Field Type Default Description
id String Required Unique item identifier.
endpoint String Required Target API URL or path.
method String 'POST' HTTP method (GET, POST, PUT, DELETE, PATCH).
payload dynamic null JSON body payload or request data.
headers Map<String, String>? null HTTP headers.
idempotencyKey String? null Key to prevent duplicate requests.
priority OutboxPriority normal critical, high, normal, or low.

πŸ’– Support the Project #

If you find this project useful, consider supporting its active maintenance and future development:

Buy Me A Coffee GitHub Sponsors Patreon


πŸ“„ License #

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Maintained with ❀️ by Govind Tank.

2
likes
160
points
442
downloads

Documentation

API reference

Publisher

verified publishergovindtank.is-a.dev

Weekly Downloads

Resilient offline-first outbox and retry queue for Dart and Flutter with disk persistence, exponential backoff, priority scheduling, and deduplication.

Repository (GitHub)
View/report issues

Topics

#offline #outbox #retry #networking #queue

License

Apache-2.0 (license)

More

Packages that depend on offline_outbox