Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,17 +1,70 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import 'dart:async';
import 'package:amplify_core/amplify_core.dart';
import 'package:amplify_core/src/types/storage/base/storage_operation.dart';
import 'package:amplify_core/src/types/storage/base/storage_controllable_operation.dart';

/// {@template amplify_core.storage.remove_operation}
/// Presents a storage remove many operation.
/// Presents a storage remove operation with enhanced capabilities.
///
/// This operation implements Future<Result> for backward compatibility
/// while providing additional features like cancellation and state tracking.
/// {@endtemplate}
class StorageRemoveOperation<
Request extends StorageRemoveRequest,
Result extends StorageRemoveResult
>
extends StorageOperation<Request, Result> {
> extends StorageOperation<Request, Result>
implements Future<Result>, StorageCancelableOperation {

/// {@macro amplify_core.storage.remove_operation}
StorageRemoveOperation({required super.request, required super.result});
StorageRemoveOperation({
required super.request,
required super.result,
required Future<void> Function() cancelFunction,
}) : _cancelFunction = cancelFunction;

/// Internal cancellation function
final Future<void> Function() _cancelFunction;

/// Current state of the operation
StorageOperationState get state => _state;
StorageOperationState _state = StorageOperationState.inProgress;

/// Cancellation implementation
@override
Future<void> cancel() => _cancelFunction();

// Future<Result> implementation for backward compatibility
@override
Stream<Result> asStream() => result.asStream();

@override
Future<Result> catchError(Function onError, {bool Function(Object error)? test}) =>
result.catchError(onError, test: test);

@override
Future<S> then<S>(FutureOr<S> Function(Result value) onValue, {Function? onError}) =>
result.then(onValue, onError: onError);

@override
Future<Result> timeout(Duration timeLimit, {FutureOr<Result> Function()? onTimeout}) =>
result.timeout(timeLimit, onTimeout: onTimeout);

@override
Future<Result> whenComplete(FutureOr<void> Function() action) =>
result.whenComplete(action);
}

/// State of a storage operation
enum StorageOperationState {
/// Operation is in progress
inProgress,
/// Operation completed successfully
success,
/// Operation was cancelled
cancelled,
/// Operation failed with error
error,
}
110 changes: 108 additions & 2 deletions packages/amplify_core/lib/src/types/storage/remove_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,56 @@ class StorageRemoveOptions
AWSSerializable<Map<String, Object?>>,
AWSDebuggable {
/// {@macro amplify_core.storage.remove_options}
const StorageRemoveOptions({this.pluginOptions, this.bucket});
const StorageRemoveOptions({
this.pluginOptions,
this.bucket,
this.recursive,
this.batchSize,
this.batchStrategy,
this.delayBetweenBatchesMs,
this.maxConcurrency,
this.errorHandling,
this.onProgress,
});

/// {@macro amplify_core.storage.remove_plugin_options}
final StorageRemovePluginOptions? pluginOptions;

/// Optionally specify which bucket to target
final StorageBucket? bucket;

/// Enable recursive folder deletion. When true, deletes all contents within the folder.
final bool? recursive;

/// Number of files to process per batch. Default: 1000 (S3 maximum).
final int? batchSize;

/// Strategy for processing batches.
final StorageBatchStrategy? batchStrategy;

/// Delay in milliseconds between batch operations.
final int? delayBetweenBatchesMs;

/// Maximum number of concurrent batch operations when using 'parallel' strategy.
final int? maxConcurrency;

/// Error handling strategy.
final StorageErrorHandling? errorHandling;

/// Callback function invoked after each batch completes.
final void Function(StorageRemoveProgressInfo)? onProgress;

@override
List<Object?> get props => [pluginOptions, bucket];
List<Object?> get props => [
pluginOptions,
bucket,
recursive,
batchSize,
batchStrategy,
delayBetweenBatchesMs,
maxConcurrency,
errorHandling,
];

@override
String get runtimeTypeName => 'StorageRemoveOptions';
Expand All @@ -30,9 +70,75 @@ class StorageRemoveOptions
Map<String, Object?> toJson() => {
'pluginOptions': pluginOptions?.toJson(),
'bucket': bucket?.toJson(),
'recursive': recursive,
'batchSize': batchSize,
'batchStrategy': batchStrategy?.name,
'delayBetweenBatchesMs': delayBetweenBatchesMs,
'maxConcurrency': maxConcurrency,
'errorHandling': errorHandling?.name,
};
}

/// Strategy for processing batches.
enum StorageBatchStrategy {
/// Process one batch at a time
sequential,
/// Process multiple batches concurrently
parallel,
}

/// Error handling strategy.
enum StorageErrorHandling {
/// Stop on first error
failEarly,
/// Process all batches regardless of errors
continueOnError,
}

/// Progress information for remove operations.
class StorageRemoveProgressInfo
with AWSEquatable<StorageRemoveProgressInfo>, AWSDebuggable {
const StorageRemoveProgressInfo({
required this.totalFiles,
required this.deletedFiles,
required this.failedFiles,
required this.currentBatch,
required this.totalBatches,
this.errors = const [],
});

/// Total number of files to delete
final int totalFiles;

/// Number of files successfully deleted
final int deletedFiles;

/// Number of files that failed to delete
final int failedFiles;

/// Current batch being processed
final int currentBatch;

/// Total number of batches
final int totalBatches;

/// List of errors encountered
final List<StorageException> errors;

@override
List<Object?> get props => [
totalFiles,
deletedFiles,
failedFiles,
currentBatch,
totalBatches,
errors,
];

@override
String get runtimeTypeName => 'StorageRemoveProgressInfo';
}

/// {@template amplify_core.storage.remove_plugin_options}
/// Plugin-specific options for `Amplify.Storage.remove`.
/// {@endtemplate}
Expand Down
Loading