ma_ng_outbox 0.0.8
ma_ng_outbox: ^0.0.8 copied to clipboard
Mariapps Internal Package to build Flutter apps faster
๐ฆ Offline Outbox Sync for Flutter (ObjectBox + Isolate + Retry + Multipart Support)
A powerful and lightweight offline-first outbox queue system for Flutter apps. Designed for real-world enterprise use cases where network instability, large payloads, and token expiry must be handled automatically.
Supports:
โ JSON API requests
โ Multipart file uploads
โ Multiple files per request
โ Empty multipart field names
โ Automatic retry with priority
โ Automatic token refresh (401 handling)
โ Runs in Isolate for non-blocking UI
โ ObjectBox storage for fast persistence
โ Fully background-safe
๐ Features Feature Status JSON request outbox โ Multipart upload (files/images/docs) โ Multiple files with dynamic field names โ Empty file field name ("") support โ Priority-based queue (1 โ 4) โ Automatic retry on failures โ Retry with new token on 401 โ Save status code + response โ RootIsolateToken support โ Zero UI freeze Isolate-based Production-ready ๐ฅ ๐ฆ Installation
Add to pubspec.yaml:
dependencies: ma_ng_outbox: git: url: https://github.com/
Make sure ObjectBox is installed:
dependencies: objectbox: any objectbox_flutter_libs: any
Run:
flutter pub get
๐ Basic Setup 1๏ธโฃ Initialize Outbox in main.dart void main() async { WidgetsFlutterBinding.ensureInitialized();
await OutboxBootstrap.setup();
runApp(MyApp()); }
๐งฑ How Outbox Works
Every API call is stored as an OutboxItem:
await objectBox.addToOutbox( operation: "POST", url: "https://api.server.com/save", payload: {"title": "Offline Save"}, priority: Priority.high, primaryKey: "local-123", );
Then Outbox will:
โ Automatically sync when online โ Retry failed requests โ Retry 401 using refresh token โ Save response & status code โ Process highest priority first ๐งต Architecture Overview UI Layer โโโโโโบ addToOutbox() โโโโโโโบ ObjectBox storage โ โผ Background Sync Trigger โ โผ Isolate Spawned โ โผ outboxIsolateEntry() reads pending items โ โโโโบ JSON Request โโโโบ Multipart Request โโโโบ Multi-file Upload โโโโบ Retry on 401 w/ Refresh Token โ โผ Main Isolate receives result โ โผ Update ObjectBox (status + response)
๐ก Adding JSON Requests await objectBox.addToOutbox( operation: "POST", url: Api.saveData, payload: { "name": "Offline Entry", "timestamp": DateTime.now().toString(), }, priority: Priority.medium, );
๐ Adding File Upload Requests 1 file await objectBox.addToOutbox( operation: "POST", url: Api.uploadImage, payload: { "description": "Offline photo", "userId": 12, }, filePathsJson: jsonEncode([imageFile.path]), fileFieldsJson: jsonEncode(["file"]), // or "" );
Multiple files await objectBox.addToOutbox( operation: "POST", url: Api.uploadDocuments, payload: {"caseId": 55}, filePathsJson: jsonEncode([frontPath, backPath]), fileFieldsJson: jsonEncode(["front", "back"]), );
๐ Token Refresh Flow (401 Handling)
If API returns 401 Unauthorized:
Call refresh token endpoint
Save new accessToken into OutboxItem
Retry original request
Continue syncing
This is built-in automatically.
๐ฆ OutboxItem Fields class OutboxItem { int id; String operation; String url; int priority; // 1โ4 String? payload; // JSON body String? response; // Server response String? filePathsJson; // ["path1","path2"] String? fileFieldsJson;// ["file",""] int isSynced; // 0 or 1 int retryCount; int lastTried; int createdAt; int? statusCode; // HTTP code String? newAccessToken; }
๐ Manual Triggering of Sync
If internet becomes available:
SyncController.runIsolateSync( objectBox: objectBox, token: "
๐ Network Listener Example ConnectivityService().onNetworkChange.listen((online) { if (online) SyncController.runIsolateSync(...); });
๐งช Debugging
Enable console logs:
kDebugMode ? print("...") : null;
View saved data using ObjectBox Admin:
if (Admin.isAvailable()) { Admin(objectBox.store); }
๐ Performance & Scaling
25,000+ outbox items tested
Large file uploads supported
No UI freeze due to isolate-based processing
Suitable for enterprise offline apps