HTTP request utilities including fetch implementations, retry logic, and data serialization for network operations.
Cross-browser fetch implementation with polyfill support.
const fetch = require('fbjs/lib/fetch');
/**
* Fetch API implementation
* Uses global.fetch if available, otherwise cross-fetch polyfill
*
* @param input - URL string or Request object
* @param init - Optional request configuration
* @returns Promise that resolves to Response object
*/
function fetch(input: string | Request, init?: RequestInit): Promise<Response>;
// RequestInit interface for configuration
interface RequestInit {
method?: string; // HTTP method (GET, POST, PUT, DELETE, etc.)
headers?: Headers | Object; // Request headers
body?: BodyInit; // Request body (string, FormData, etc.)
mode?: RequestMode; // CORS mode (cors, no-cors, same-origin)
credentials?: RequestCredentials; // Credentials mode (omit, same-origin, include)
cache?: RequestCache; // Cache mode (default, no-store, reload, etc.)
redirect?: RequestRedirect; // Redirect mode (follow, error, manual)
referrer?: string; // Referrer
referrerPolicy?: ReferrerPolicy; // Referrer policy
integrity?: string; // Subresource integrity
signal?: AbortSignal; // AbortController signal for cancellation
}
// Response interface
interface Response {
ok: boolean; // True if status in 200-299 range
status: number; // HTTP status code
statusText: string; // HTTP status text
headers: Headers; // Response headers
url: string; // Response URL
redirected: boolean; // True if response is result of redirect
type: ResponseType; // Response type (basic, cors, error, etc.)
// Body parsing methods
text(): Promise<string>;
json(): Promise<any>;
blob(): Promise<Blob>;
arrayBuffer(): Promise<ArrayBuffer>;
formData(): Promise<FormData>;
// Body stream
body: ReadableStream;
bodyUsed: boolean;
// Cloning
clone(): Response;
}Usage Examples:
const fetch = require('fbjs/lib/fetch');
// Simple GET request
fetch('https://api.example.com/users')
.then(response => {
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return response.json();
})
.then(users => {
console.log('Users:', users);
})
.catch(error => {
console.error('Fetch error:', error);
});
// POST request with JSON data
const newUser = {
name: 'Alice Johnson',
email: 'alice@example.com'
};
fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + token
},
body: JSON.stringify(newUser)
})
.then(response => response.json())
.then(createdUser => {
console.log('Created user:', createdUser);
});
// Request with AbortController for cancellation
const controller = new AbortController();
const signal = controller.signal;
// Cancel request after 5 seconds
setTimeout(() => controller.abort(), 5000);
fetch('https://api.example.com/large-data', { signal })
.then(response => response.json())
.catch(error => {
if (error.name === 'AbortError') {
console.log('Request was cancelled');
} else {
console.error('Request failed:', error);
}
});
// Upload file with FormData
const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('description', 'Profile picture');
fetch('https://api.example.com/upload', {
method: 'POST',
body: formData
})
.then(response => response.json());Enhanced fetch implementation with automatic retry logic for failed requests.
const fetchWithRetries = require('fbjs/lib/fetchWithRetries');
/**
* Fetch with automatic retry logic for failed requests
* @param uri - URL to fetch
* @param initWithRetries - Request configuration with retry options
* @returns Promise that resolves to Response object
*/
function fetchWithRetries(uri: string, initWithRetries?: RequestInitWithRetries): Promise<Response>;
// Extended RequestInit with retry configuration
interface RequestInitWithRetries extends RequestInit {
// Standard fetch options
method?: string;
headers?: Headers | Object;
body?: BodyInit;
mode?: RequestMode;
credentials?: RequestCredentials;
cache?: RequestCache;
redirect?: RequestRedirect;
// Retry-specific options
retries?: number; // Maximum number of retry attempts (default: 3)
retryDelayType?: 'fixed' | 'linear' | 'exponential'; // Delay strategy (default: 'exponential')
retryDelayMS?: number; // Base delay in milliseconds (default: 1000)
retryDelayMax?: number; // Maximum delay in milliseconds (default: 10000)
shouldRetry?: (error: Error, attempt: number) => boolean; // Custom retry predicate
onRetryAttempt?: (attempt: number, delay: number) => void; // Retry attempt callback
}Usage Examples:
const fetchWithRetries = require('fbjs/lib/fetchWithRetries');
// Basic retry with default settings (3 retries, exponential backoff)
fetchWithRetries('https://api.example.com/unreliable-endpoint')
.then(response => response.json())
.then(data => {
console.log('Data received after retries:', data);
})
.catch(error => {
console.error('Failed after all retries:', error);
});
// Custom retry configuration
fetchWithRetries('https://api.example.com/data', {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + token
},
retries: 5, // Try up to 5 times
retryDelayType: 'linear', // Linear delay increase
retryDelayMS: 500, // Start with 500ms delay
retryDelayMax: 5000, // Max 5 second delay
shouldRetry: (error, attempt) => {
// Only retry on network errors or 5xx status codes
return error.name === 'TypeError' ||
(error.status && error.status >= 500);
},
onRetryAttempt: (attempt, delay) => {
console.log(`Retry attempt ${attempt} after ${delay}ms delay`);
}
})
.then(response => {
console.log('Request succeeded on attempt:', response);
});
// Retry with exponential backoff for POST requests
const postData = { message: 'Important data' };
fetchWithRetries('https://api.example.com/messages', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(postData),
retries: 3,
retryDelayType: 'exponential',
retryDelayMS: 1000, // 1s, 2s, 4s delays
shouldRetry: (error, attempt) => {
// Don't retry client errors (4xx), only server errors (5xx) and network issues
if (error.status) {
return error.status >= 500;
}
return true; // Network error, retry
}
})
.then(response => response.json())
.then(result => {
console.log('Message sent successfully:', result);
})
.catch(error => {
console.error('Failed to send message after retries:', error);
});Utilities for serializing data for HTTP requests.
const xhrSimpleDataSerializer = require('fbjs/lib/xhrSimpleDataSerializer');
/**
* Serializes data for XHR requests into URL-encoded format
* @param data - Data object to serialize
* @returns URL-encoded string representation of data
*/
function xhrSimpleDataSerializer(data: any): string;Usage Examples:
const xhrSimpleDataSerializer = require('fbjs/lib/xhrSimpleDataSerializer');
// Serialize object for form submission
const formData = {
username: 'alice@example.com',
password: 'secret123',
remember: true,
preferences: ['email', 'sms']
};
const serialized = xhrSimpleDataSerializer(formData);
console.log(serialized);
// Output: "username=alice%40example.com&password=secret123&remember=true&preferences=email&preferences=sms"
// Use with traditional XMLHttpRequest
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/login');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(serialized);
// Use with fetch for form-encoded POST
const loginData = {
email: 'user@example.com',
password: 'mypassword'
};
fetch('https://api.example.com/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: xhrSimpleDataSerializer(loginData)
})
.then(response => response.json());
// Handle nested objects and arrays
const complexData = {
user: {
name: 'John Doe',
age: 30
},
tags: ['developer', 'javascript'],
active: true
};
const complexSerialized = xhrSimpleDataSerializer(complexData);
// Handles nested structures appropriately for form encodingUtilities for handling data transfer operations and file types.
const DataTransfer = require('fbjs/lib/DataTransfer');
const PhotosMimeType = require('fbjs/lib/PhotosMimeType');
/**
* Data transfer utilities for drag-and-drop and clipboard operations
*/
class DataTransfer {
/**
* Creates a new DataTransfer instance
*/
constructor();
/**
* Gets files from transfer operation
* @returns Array of File objects
*/
getFiles(): Array<File>;
/**
* Gets text data from transfer
* @param format - MIME type or format (e.g., 'text/plain', 'text/html')
* @returns Text data or null if not available
*/
getData(format: string): ?string;
/**
* Sets text data for transfer
* @param format - MIME type or format
* @param data - Text data to set
*/
setData(format: string, data: string): void;
/**
* Checks if specific data type is available
* @param format - MIME type or format to check
* @returns True if data type is available
*/
hasType(format: string): boolean;
/**
* Gets list of available data types
* @returns Array of available MIME types/formats
*/
getTypes(): Array<string>;
/**
* Clears all data from transfer
*/
clearData(): void;
}
/**
* Photo and image MIME type utilities
*/
const PhotosMimeType: {
/**
* Checks if MIME type is a supported image format
* @param mimeType - MIME type string
* @returns True if MIME type represents an image
*/
isImage(mimeType: string): boolean;
/**
* Checks if MIME type is a photo format (excludes SVG, etc.)
* @param mimeType - MIME type string
* @returns True if MIME type is a photo format
*/
isPhoto(mimeType: string): boolean;
/**
* Gets file extension for MIME type
* @param mimeType - Image MIME type
* @returns File extension (e.g., 'jpg', 'png') or null
*/
getExtension(mimeType: string): ?string;
/**
* Gets MIME type for file extension
* @param extension - File extension (with or without dot)
* @returns MIME type string or null
*/
getMimeType(extension: string): ?string;
/**
* Gets list of supported image MIME types
* @returns Array of supported MIME type strings
*/
getSupportedTypes(): Array<string>;
/**
* Validates if file is an acceptable image format
* @param file - File object to validate
* @returns True if file is acceptable image format
*/
isValidImageFile(file: File): boolean;
};Usage Examples:
const DataTransfer = require('fbjs/lib/DataTransfer');
const PhotosMimeType = require('fbjs/lib/PhotosMimeType');
// Handle drag and drop
function handleDrop(event) {
const transfer = new DataTransfer();
const files = transfer.getFiles();
files.forEach(file => {
if (PhotosMimeType.isPhoto(file.type)) {
console.log('Dropped photo:', file.name);
// Process photo file
} else {
console.log('Not a photo format:', file.type);
}
});
// Get text data if available
const htmlContent = transfer.getData('text/html');
const plainText = transfer.getData('text/plain');
}
// MIME type validation
const mimeTypes = ['image/jpeg', 'image/png', 'image/svg+xml', 'text/plain'];
mimeTypes.forEach(type => {
console.log(`${type}:`);
console.log(` Is image: ${PhotosMimeType.isImage(type)}`);
console.log(` Is photo: ${PhotosMimeType.isPhoto(type)}`);
console.log(` Extension: ${PhotosMimeType.getExtension(type)}`);
});
// File upload validation
function validateImageUpload(file) {
if (!PhotosMimeType.isValidImageFile(file)) {
throw new Error('Invalid image file type');
}
if (PhotosMimeType.isPhoto(file.type)) {
console.log('Uploading photo:', file.name);
} else {
console.log('Uploading image:', file.name);
}
}
// Get supported formats for file input
const supportedTypes = PhotosMimeType.getSupportedTypes();
const accept = supportedTypes.join(',');
// Use in HTML: <input type="file" accept="image/jpeg,image/png,..." />