Utilities
Framework-agnostic utility functions for common file operations and tasks.
File Utilities
generateId()
Generate a unique ID for files or queue items:
import { generateId } from '@dropper/core'
const id = generateId()
console.log(id) // "1699564800000-a1b2c3d4e"
Format: {timestamp}-{random}
- Timestamp: Current time in milliseconds
- Random: 9-character alphanumeric string
Use Cases:
- Unique queue item IDs
- Temporary file identifiers
- Client-side tracking
formatFileSize()
Convert bytes to human-readable file size:
import { formatFileSize } from '@dropper/core'
formatFileSize(0) // "0 Bytes"
formatFileSize(1024) // "1 KB"
formatFileSize(1048576) // "1 MB"
formatFileSize(1073741824) // "1 GB"
formatFileSize(1536) // "1.5 KB"
Parameters:
bytes(number): File size in bytes
Returns: Formatted string with appropriate unit
getFileExtension()
Extract file extension from filename:
import { getFileExtension } from '@dropper/core'
getFileExtension('photo.jpg') // "jpg"
getFileExtension('document.pdf') // "pdf"
getFileExtension('archive.tar.gz') // "gz"
getFileExtension('README') // ""
Parameters:
filename(string): File name
Returns: Lowercase extension without dot, or empty string
getMimeTypeCategory()
Get the category of a MIME type:
import { getMimeTypeCategory } from '@dropper/core'
getMimeTypeCategory('image/jpeg') // "image"
getMimeTypeCategory('video/mp4') // "video"
getMimeTypeCategory('audio/mpeg') // "audio"
getMimeTypeCategory('application/pdf') // "pdf"
getMimeTypeCategory('text/plain') // "document"
getMimeTypeCategory('application/msword') // "document"
getMimeTypeCategory('application/zip') // "file"
Categories:
image- Image filesvideo- Video filesaudio- Audio filespdf- PDF documentsdocument- Text and document filesfile- Other file types
Date Utilities
formatDate()
Format a date to ISO string:
import { formatDate } from '@dropper/core'
const date = new Date('2024-01-15T10:30:00')
formatDate(date) // "2024-01-15T10:30:00.000Z"
// Also accepts string input
formatDate('2024-01-15') // "2024-01-15T00:00:00.000Z"
Parameters:
date(Date | string): Date object or date string
Returns: ISO 8601 formatted string
Function Utilities
debounce()
Debounce a function to limit execution rate:
import { debounce } from '@dropper/core'
const searchFiles = debounce((query: string) => {
console.log('Searching for:', query)
// API call here
}, 300)
// Called multiple times rapidly
searchFiles('doc')
searchFiles('docu')
searchFiles('document')
// Only executes once after 300ms of inactivity
Parameters:
func(Function): Function to debouncewait(number): Delay in milliseconds
Returns: Debounced function
Use Cases:
- Search input handling
- Window resize events
- Scroll events
- Form validation
throttle()
Throttle a function to execute at most once per interval:
import { throttle } from '@dropper/core'
const handleScroll = throttle(() => {
console.log('Scroll position:', window.scrollY)
}, 100)
window.addEventListener('scroll', handleScroll)
// Executes at most once every 100ms
Parameters:
func(Function): Function to throttlelimit(number): Minimum interval in milliseconds
Returns: Throttled function
Use Cases:
- Scroll events
- Mouse move events
- API rate limiting
- Animation frames
sleep()
Pause execution for a specified duration:
import { sleep } from '@dropper/core'
async function delayedAction() {
console.log('Starting...')
await sleep(2000) // Wait 2 seconds
console.log('Done!')
}
Parameters:
ms(number): Duration in milliseconds
Returns: Promise that resolves after delay
Use Cases:
- Artificial delays
- Rate limiting
- Animation timing
- Testing
retry()
Retry a function with exponential backoff:
import { retry } from '@dropper/core'
const result = await retry(
async () => {
// Function that might fail
return await fetchData()
},
{
maxRetries: 3,
initialDelay: 1000,
maxDelay: 10000,
backoffFactor: 2,
}
)
Parameters:
fn(Function): Async function to retryoptions(object):maxRetries(number): Maximum retry attempts (default: 3)initialDelay(number): Initial delay in ms (default: 1000)maxDelay(number): Maximum delay in ms (default: 10000)backoffFactor(number): Backoff multiplier (default: 2)
Returns: Promise with function result
Retry Schedule:
- Attempt 1: Immediate
- Attempt 2: After 1s (initialDelay)
- Attempt 3: After 2s (initialDelay × backoffFactor)
- Attempt 4: After 4s (initialDelay × backoffFactor²)
Complete Examples
File Upload with Formatting
import {
formatFileSize,
getFileExtension,
getMimeTypeCategory
} from '@dropper/core'
function displayFileInfo(file: File) {
console.log('File Information:')
console.log(`Name: ${file.name}`)
console.log(`Size: ${formatFileSize(file.size)}`)
console.log(`Extension: ${getFileExtension(file.name)}`)
console.log(`Category: ${getMimeTypeCategory(file.type)}`)
console.log(`Type: ${file.type}`)
}
// Example output:
// File Information:
// Name: photo.jpg
// Size: 2.5 MB
// Extension: jpg
// Category: image
// Type: image/jpeg
Search with Debounce
import { debounce } from '@dropper/core'
import { DropperClient } from '@dropper/core'
const client = new DropperClient({
publishableKey: 'pk_dropper_test_xxx',
})
const searchFiles = debounce(async (query: string) => {
if (query.length < 2) return
const results = await client.listFiles({
search: query,
limit: 10,
})
displayResults(results.data)
}, 300)
// Usage in input handler
function handleSearchInput(e: Event) {
const query = (e.target as HTMLInputElement).value
searchFiles(query)
}
Retry Failed Upload
import { retry, sleep } from '@dropper/core'
import { DropperClient } from '@dropper/core'
const client = new DropperClient({
publishableKey: 'pk_dropper_test_xxx',
})
async function uploadWithRetry(file: File) {
try {
const result = await retry(
async () => {
console.log('Attempting upload...')
return await client.uploadFile(file)
},
{
maxRetries: 3,
initialDelay: 1000,
backoffFactor: 2,
}
)
console.log('Upload successful:', result.url)
return result
} catch (error) {
console.error('Upload failed after retries:', error)
throw error
}
}
Throttled Progress Updates
import { throttle } from '@dropper/core'
const updateUI = throttle((progress: number) => {
// Update progress bar
progressBar.style.width = `${progress}%`
progressText.textContent = `${progress}%`
}, 100)
// Upload with throttled updates
await client.uploadFile(file, {
onProgress: (progress) => {
updateUI(progress)
},
})
File List with Formatting
import { formatFileSize, formatDate, getMimeTypeCategory } from '@dropper/core'
async function displayFileList() {
const response = await client.listFiles()
response.data.forEach((file) => {
const category = getMimeTypeCategory(file.mimeType)
const size = formatFileSize(file.size)
const date = new Date(file.createdAt).toLocaleDateString()
console.log(`[${category}] ${file.originalFilename}`)
console.log(` Size: ${size}`)
console.log(` Uploaded: ${date}`)
console.log()
})
}
Generate Unique IDs
import { generateId } from '@dropper/core'
// Create upload queue items
const queueItems = files.map((file) => ({
id: generateId(),
file,
status: 'pending',
progress: 0,
}))
// Track uploads
const uploadTracking = new Map()
files.forEach((file) => {
const trackingId = generateId()
uploadTracking.set(trackingId, {
file,
startTime: Date.now(),
})
})
React Integration Examples
Debounced Search Component
import { useState, useCallback } from 'react'
import { debounce } from '@dropper/core'
function FileSearch() {
const [results, setResults] = useState([])
const searchFiles = useCallback(
debounce(async (query: string) => {
const response = await client.listFiles({ search: query })
setResults(response.data)
}, 300),
[]
)
return (
<input
type="search"
onChange={(e) => searchFiles(e.target.value)}
placeholder="Search files..."
/>
)
}
File Size Display
import { formatFileSize } from '@dropper/core'
function FileListItem({ file }) {
return (
<div>
<span>{file.originalFilename}</span>
<span>{formatFileSize(file.size)}</span>
</div>
)
}
Best Practices
1. Use Debounce for User Input
Reduce API calls for search and filter inputs:
const searchFiles = debounce(async (query) => {
await client.listFiles({ search: query })
}, 300)
2. Use Throttle for Frequent Events
Limit execution rate for scroll, resize, and mouse events:
const handleScroll = throttle(() => {
// Handle scroll
}, 100)
3. Format File Sizes for Display
Always format file sizes for user display:
// Good
console.log(`Size: ${formatFileSize(file.size)}`)
// Avoid
console.log(`Size: ${file.size} bytes`)
4. Use Retry for Network Operations
Add retry logic for unreliable network operations:
await retry(async () => {
return await client.uploadFile(file)
}, { maxRetries: 3 })
5. Generate Unique IDs Client-Side
Use generateId() for client-side tracking:
const queueItem = {
id: generateId(),
file,
status: 'pending',
}
TypeScript Support
All utilities are fully typed:
import type {
generateId,
formatFileSize,
debounce,
throttle,
retry,
} from '@dropper/core'
// Type-safe usage
const id: string = generateId()
const size: string = formatFileSize(1024)
const debouncedFn = debounce((x: string) => console.log(x), 300)
Next Steps
- File Upload - Use utilities in upload workflows
- File Management - Format file information
- Validation - Combine with validation utilities