fetchWithAuthAndCreateBlob method

Future<String> fetchWithAuthAndCreateBlob(
  1. String url,
  2. String authToken, {
  3. required void onProgress(
    1. double progress
    ),
})

Fetches a file with authentication and creates a blob URL.

Returns a blob URL that can be used with MediaPipe. Calls onProgress with download progress (0.0 to 1.0).

Throws JsInteropException on fetch errors (network, auth, etc.).

Implementation

Future<String> fetchWithAuthAndCreateBlob(
  String url,
  String authToken, {
  required void Function(double progress) onProgress,
}) async {
  try {
    // 1. Create fetch options with auth header
    final options = _createFetchOptions(authToken);

    // 2. Fetch with auth
    final response = await _fetch(url, options);

    // 3. Check response status
    if (!response.isOk) {
      final statusCode = response.statusCode;
      final statusText = response.statusMessage;

      if (statusCode == 401) {
        throw JsInteropException(
          'Authentication failed: Invalid or expired token',
          statusCode: 401,
        );
      } else if (statusCode == 403) {
        throw JsInteropException(
          'Access denied: Token lacks required permissions',
          statusCode: 403,
        );
      } else if (statusCode == 404) {
        throw JsInteropException(
          'Model not found: Check URL is correct',
          statusCode: 404,
        );
      } else {
        throw JsInteropException(
          'HTTP $statusCode: $statusText',
          statusCode: statusCode,
        );
      }
    }

    // 4. Get content length for progress
    final contentLength = _getContentLength(response);

    // 5. Stream response body
    final chunks = await _streamResponseBody(
      response,
      contentLength,
      onProgress,
    );

    // 6. Create blob from chunks
    final blob = _createBlob(chunks);

    // 7. Create and return blob URL
    final blobUrl = _createBlobUrl(blob);

    return blobUrl;

  } catch (e) {
    if (e is JsInteropException) rethrow;

    // Check for common error patterns
    final errorStr = e.toString();
    if (errorStr.contains('CORS') || errorStr.contains('Access-Control')) {
      throw JsInteropException(
        'CORS error: Server does not allow requests from this origin. '
        'For HuggingFace models, ensure you have access to the repository.',
      );
    } else if (errorStr.contains('network') || errorStr.contains('Failed to fetch')) {
      throw JsInteropException(
        'Network error: Check your internet connection and try again.',
      );
    } else {
      throw JsInteropException('Fetch failed: $e');
    }
  }
}