getOrCacheAndRegisterWithProgress method
Universal caching wrapper with progress tracking (stream version)
Checks cache first (if enabled), loads if needed, caches (if enabled), creates blob URL, registers in file system. Yields progress as int percentage (0-100).
cacheKey - Key for Cache API storage
loader - Async function that loads data and reports progress via callback
targetPath - Path to register in WebFileSystemService
Returns: Stream of progress percentages (0-100)
Implementation
Stream<int> getOrCacheAndRegisterWithProgress({
required String cacheKey,
required Future<Uint8List> Function(void Function(double) onProgress) loader,
required String targetPath,
}) async* {
try {
// 1. Check cache first (only if caching enabled)
if (enableCache) {
final cachedBlobUrl = await getCachedBlobUrl(cacheKey);
if (cachedBlobUrl != null) {
debugPrint('[WebCacheService] ✅ Found in cache: $cacheKey');
_fileSystem.registerUrl(targetPath, cachedBlobUrl);
yield 100; // Instant completion
return;
}
}
// 2. Load data with progress tracking
debugPrint('[WebCacheService] 📥 Loading: $cacheKey (cache: ${enableCache ? "enabled" : "disabled"})');
final controller = StreamController<int>();
Uint8List? loadedData;
// Start loading in background with progress callback
loader((progress) {
final percent = (progress * 100).clamp(0, 99).toInt();
if (!controller.isClosed) {
controller.add(percent);
}
}).then((data) {
loadedData = data;
if (!controller.isClosed) {
controller.close();
}
}).catchError((error) {
if (!controller.isClosed) {
controller.addError(error);
controller.close();
}
});
// Yield progress updates
await for (final progress in controller.stream) {
yield progress;
}
if (loadedData == null) {
throw Exception('Failed to load data for: $cacheKey');
}
// 3. Cache the data (only if caching enabled)
if (enableCache) {
await cacheModel(cacheKey, loadedData!);
// 4. Create blob URL from cache
final blobUrl = await getCachedBlobUrl(cacheKey);
if (blobUrl == null) {
throw Exception('Failed to create blob URL for: $cacheKey');
}
// 5. Register in file system
_fileSystem.registerUrl(targetPath, blobUrl);
debugPrint('[WebCacheService] ✅ Cached and registered: $cacheKey');
} else {
// Create temporary blob URL without caching
final blobUrl = _cacheInterop.createBlobUrl(loadedData!);
_fileSystem.registerUrl(targetPath, blobUrl);
debugPrint('[WebCacheService] ✅ Registered (no cache): $cacheKey');
}
yield 100; // Final completion
} catch (e) {
debugPrint('[WebCacheService] ❌ getOrCacheAndRegisterWithProgress failed: $e');
rethrow;
}
}