/**
* Determines whether a value is a Blob object with enhanced type safety.
*
* Provides reliable Blob detection with environment compatibility, identifying
* Blob objects used for handling binary data in web applications. Returns false
* in environments where Blob API is not available (e.g., older Node.js versions).
*
* @param value - Value to test for Blob type
* @returns Type-safe boolean indicating whether the value is a Blob object
*
* @example
* Basic Blob detection:
* ```typescript
* import { isBlob } from '@winglet/common-utils';
*
* // True cases - Blob instances (in browser environment)
* if (typeof Blob !== 'undefined') {
* const blob1 = new Blob(['Hello World'], { type: 'text/plain' });
* const blob2 = new Blob([new Uint8Array([1, 2, 3])], { type: 'application/octet-stream' });
* const blob3 = new Blob(['
HTML
'], { type: 'text/html' });
*
* console.log(isBlob(blob1)); // true
* console.log(isBlob(blob2)); // true
* console.log(isBlob(blob3)); // true
*
* // File objects are also Blobs
* const file = new File(['content'], 'test.txt', { type: 'text/plain' });
* console.log(isBlob(file)); // true (File extends Blob)
* }
*
* // False cases - not Blob objects
* console.log(isBlob('binary data')); // false (string)
* console.log(isBlob(new ArrayBuffer(16))); // false (ArrayBuffer)
* console.log(isBlob(new Uint8Array([1, 2, 3]))); // false (TypedArray)
* console.log(isBlob({ size: 100, type: 'text/plain' })); // false (blob-like object)
* console.log(isBlob(null)); // false
* console.log(isBlob(undefined)); // false
*
* // Environment without Blob API support
* console.log(isBlob(anything)); // always false
* ```
*
* @example
* File and binary data processing:
* ```typescript
* interface DataProcessor {
* processData(data: unknown): Promise;
* }
*
* interface ProcessingResult {
* success: boolean;
* type: string;
* size: number;
* content?: string;
* error?: string;
* }
*
* class BlobDataProcessor implements DataProcessor {
* async processData(data: unknown): Promise {
* if (!isBlob(data)) {
* return {
* success: false,
* type: 'unknown',
* size: 0,
* error: 'Input is not a Blob object'
* };
* }
*
* // TypeScript knows data is Blob
* try {
* const content = await this.extractContent(data);
*
* return {
* success: true,
* type: data.type || 'unknown',
* size: data.size,
* content
* };
* } catch (error) {
* return {
* success: false,
* type: data.type || 'unknown',
* size: data.size,
* error: error.message
* };
* }
* }
*
* private async extractContent(blob: Blob): Promise {
* if (blob.type.startsWith('text/')) {
* return await blob.text();
* }
*
* if (blob.type.startsWith('application/json')) {
* return await blob.text();
* }
*
* // For binary data, return base64
* const arrayBuffer = await blob.arrayBuffer();
* const uint8Array = new Uint8Array(arrayBuffer);
* return btoa(String.fromCharCode(...uint8Array));
* }
* }
* ```
*
* @example
* Image processing with Blob validation:
* ```typescript
* class ImageProcessor {
* async processImage(imageData: unknown): Promise<{
* processed: boolean;
* width?: number;
* height?: number;
* url?: string;
* error?: string;
* }> {
* if (!isBlob(imageData)) {
* return {
* processed: false,
* error: 'Expected Blob object for image processing'
* };
* }
*
* if (!imageData.type.startsWith('image/')) {
* return {
* processed: false,
* error: `Invalid image type: ${imageData.type}`
* };
* }
*
* try {
* const url = URL.createObjectURL(imageData);
* const dimensions = await this.getImageDimensions(url);
*
* return {
* processed: true,
* width: dimensions.width,
* height: dimensions.height,
* url
* };
* } catch (error) {
* return {
* processed: false,
* error: `Image processing failed: ${error.message}`
* };
* }
* }
*
* private getImageDimensions(url: string): Promise<{ width: number; height: number }> {
* return new Promise((resolve, reject) => {
* const img = new Image();
* img.onload = () => {
* URL.revokeObjectURL(url);
* resolve({ width: img.width, height: img.height });
* };
* img.onerror = () => {
* URL.revokeObjectURL(url);
* reject(new Error('Failed to load image'));
* };
* img.src = url;
* });
* }
* }
* ```
*
* @example
* API response handling:
* ```typescript
* interface ApiClient {
* downloadFile(url: string): Promise;
* uploadFile(blob: unknown): Promise<{ success: boolean; message: string }>;
* }
*
* class BlobApiClient implements ApiClient {
* async downloadFile(url: string): Promise {
* const response = await fetch(url);
*
* if (!response.ok) {
* throw new Error(`Download failed: ${response.statusText}`);
* }
*
* const blob = await response.blob();
*
* if (!isBlob(blob)) {
* throw new Error('Response is not a valid Blob');
* }
*
* return blob;
* }
*
* async uploadFile(blob: unknown): Promise<{ success: boolean; message: string }> {
* if (!isBlob(blob)) {
* return {
* success: false,
* message: 'Upload data must be a Blob object'
* };
* }
*
* const formData = new FormData();
* formData.append('file', blob);
*
* try {
* const response = await fetch('/api/upload', {
* method: 'POST',
* body: formData
* });
*
* if (response.ok) {
* return {
* success: true,
* message: `File uploaded successfully (${blob.size} bytes)`
* };
* } else {
* return {
* success: false,
* message: `Upload failed: ${response.statusText}`
* };
* }
* } catch (error) {
* return {
* success: false,
* message: `Upload error: ${error.message}`
* };
* }
* }
* }
* ```
*
* @example
* Blob creation and validation utilities:
* ```typescript
* interface BlobOptions {
* type?: string;
* endings?: 'transparent' | 'native';
* }
*
* class BlobUtils {
* static createTextBlob(text: string, options: BlobOptions = {}): Blob | null {
* if (typeof Blob === 'undefined') {
* console.warn('Blob API not supported');
* return null;
* }
*
* const blob = new Blob([text], {
* type: options.type || 'text/plain',
* endings: options.endings
* });
*
* return isBlob(blob) ? blob : null;
* }
*
* static createBinaryBlob(data: ArrayBuffer | Uint8Array, type = 'application/octet-stream'): Blob | null {
* if (typeof Blob === 'undefined') {
* console.warn('Blob API not supported');
* return null;
* }
*
* const blob = new Blob([data], { type });
* return isBlob(blob) ? blob : null;
* }
*
* static async blobToBase64(blob: unknown): Promise {
* if (!isBlob(blob)) {
* return null;
* }
*
* try {
* const arrayBuffer = await blob.arrayBuffer();
* const uint8Array = new Uint8Array(arrayBuffer);
* return btoa(String.fromCharCode(...uint8Array));
* } catch (error) {
* console.error('Failed to convert blob to base64:', error);
* return null;
* }
* }
*
* static getBlobInfo(blob: unknown): {
* isValid: boolean;
* size?: number;
* type?: string;
* } {
* if (!isBlob(blob)) {
* return { isValid: false };
* }
*
* return {
* isValid: true,
* size: blob.size,
* type: blob.type
* };
* }
* }
* ```
*
* @example
* Environment feature detection:
* ```typescript
* interface BlobApiSupport {
* blob: boolean;
* file: boolean;
* fileReader: boolean;
* url: boolean;
* formData: boolean;
* }
*
* function detectBlobApiSupport(): BlobApiSupport {
* return {
* blob: typeof Blob !== 'undefined',
* file: typeof File !== 'undefined',
* fileReader: typeof FileReader !== 'undefined',
* url: typeof URL !== 'undefined' && typeof URL.createObjectURL === 'function',
* formData: typeof FormData !== 'undefined'
* };
* }
*
* function validateBlobEnvironment(): string[] {
* const errors: string[] = [];
* const support = detectBlobApiSupport();
*
* if (!support.blob) {
* errors.push('Blob API not supported');
* }
*
* if (!support.url) {
* errors.push('URL.createObjectURL not supported');
* }
*
* if (!support.formData) {
* errors.push('FormData API not supported');
* }
*
* return errors;
* }
*
* // Usage
* const validationErrors = validateBlobEnvironment();
* if (validationErrors.length > 0) {
* console.warn('Blob features unavailable:', validationErrors);
* } else {
* console.log('Environment supports Blob operations');
* }
* ```
*
* @remarks
* **Blob Characteristics:**
* - Immutable raw data objects
* - Can represent data in various formats (text, binary, etc.)
* - Have size and optional MIME type
* - Support streaming and slicing operations
* - File objects extend Blob with additional metadata
*
* **Environment Compatibility:**
* - Available in modern browsers
* - Limited support in older browsers
* - Node.js support varies by version (may require polyfills)
* - Always check for Blob constructor existence
*
* **Common Use Cases:**
* - File upload/download handling
* - Image and media processing
* - Binary data manipulation
* - API request/response handling
* - Client-side file generation
*
* **Performance:** Direct instanceof check with environment validation provides optimal performance.
*
* **Related Functions:**
* - Use `isFile()` for File-specific detection (File extends Blob)
* - Use `isArrayBuffer()` for raw binary buffer detection
* - Use `isTypedArray()` for typed binary array detection
*/
export declare const isBlob: (value: unknown) => value is Blob;