Exemplos de Recursos Web Web TypeScript
Exemplos de recursos web Web TypeScript incluindo roteamento, middleware e serviço de arquivos estáticos
Key Facts
- Category
- TypeScript
- Items
- 3
- Format Families
- sample
Sample Overview
Exemplos de recursos web Web TypeScript incluindo roteamento, middleware e serviço de arquivos estáticos This sample set belongs to TypeScript and can be used to test related workflows inside Elysia Tools.
💻 Roteamento typescript
🟡 intermediate
⭐⭐⭐
Analisar rotas de URL, lidar com roteamento hash e gerenciar histórico do navegador
⏱️ 25 min
🏷️ typescript, web, web features
Prerequisites:
Intermediate TypeScript, History API, URL API
// Web TypeScript Routing Examples
// Client-side routing with URL parsing, hash routing, and history management
// 1. Route Interface
interface Route {
path: string;
handler: (params: Record<string, string>, query: Record<string, string>) => void;
}
// 2. Router
class Router {
private routes: Route[] = [];
private notFoundHandler?: () => void;
private currentParams: Record<string, string> = {};
private currentQuery: Record<string, string> = {};
// Add route
addRoute(path: string, handler: Route['handler']): void {
this.routes.push({ path, handler });
}
// Set 404 handler
setNotFound(handler: () => void): void {
this.notFoundHandler = handler;
}
// Navigate to path
navigate(path: string, params: Record<string, string> = {}): void {
// Build URL with params
let url = path;
if (Object.keys(params).length > 0) {
url = this.replaceParams(path, params);
}
// Update browser URL
window.history.pushState({}, '', url);
// Handle route
this.handleRoute(url);
}
// Replace current route
replace(path: string, params: Record<string, string> = {}): void {
let url = path;
if (Object.keys(params).length > 0) {
url = this.replaceParams(path, params);
}
window.history.replaceState({}, '', url);
this.handleRoute(url);
}
// Go back
back(): void {
window.history.back();
}
// Go forward
forward(): void {
window.history.forward();
}
// Go to specific history entry
go(delta: number): void {
window.history.go(delta);
}
// Handle route change
private handleRoute(url: string): void {
const { path, query } = this.parseURL(url);
// Find matching route
const route = this.findRoute(path);
if (route) {
const params = this.extractParams(path, route.path);
this.currentParams = params;
this.currentQuery = query;
route.handler(params, query);
} else if (this.notFoundHandler) {
this.notFoundHandler();
}
}
// Find matching route
private findRoute(path: string): Route | null {
for (const route of this.routes) {
if (this.matchRoute(path, route.path)) {
return route;
}
}
return null;
}
// Check if path matches route pattern
private matchRoute(path: string, pattern: string): boolean {
// Convert pattern to regex
const regexPattern = pattern
.replace(/:\\w+/g, '([^/]+)')
.replace(/\\*/g, '.*');
const regex = new RegExp(`^${regexPattern}$`);
return regex.test(path);
}
// Extract params from path
private extractParams(path: string, pattern: string): Record<string, string> {
const params: Record<string, string> = {};
const patternParts = pattern.split('/');
const pathParts = path.split('/');
for (let i = 0; i < patternParts.length; i++) {
const part = patternParts[i];
if (part.startsWith(':')) {
const paramName = part.substring(1);
params[paramName] = pathParts[i] || '';
}
}
return params;
}
// Replace params in path
private replaceParams(path: string, params: Record<string, string>): string {
let result = path;
for (const [key, value] of Object.entries(params)) {
result = result.replace(`:${key}`, value);
}
return result;
}
// Parse URL into path and query
private parseURL(url: string): {
path: string;
query: Record<string, string>;
} {
const [path, queryString] = url.split('?');
const query: Record<string, string> = {};
if (queryString) {
const params = new URLSearchParams(queryString);
params.forEach((value, key) => {
query[key] = value;
});
}
return { path, query };
}
// Initialize router
initialize(): void {
// Handle popstate event (back/forward buttons)
window.addEventListener('popstate', () => {
this.handleRoute(window.location.pathname);
});
// Handle initial route
this.handleRoute(window.location.pathname);
}
}
// 3. Hash Router
class HashRouter {
private routes: Route[] = [];
private notFoundHandler?: () => void;
// Add route
addRoute(path: string, handler: Route['handler']): void {
// Remove leading slash for hash matching
const hashPath = path.startsWith('/') ? path.substring(1) : path;
this.routes.push({ path: hashPath, handler });
}
// Set 404 handler
setNotFound(handler: () => void): void {
this.notFoundHandler = handler;
}
// Navigate to hash
navigate(hash: string, params: Record<string, string> = {}): void {
let url = hash;
if (Object.keys(params).length > 0) {
url = this.replaceParams(hash, params);
}
window.location.hash = url;
}
// Get current hash
getHash(): string {
return window.location.hash.substring(1) || '/';
}
// Handle hash change
private handleHashChange(): void {
const hash = this.getHash();
const [path, queryString] = hash.split('?');
const query: Record<string, string> = {};
if (queryString) {
const params = new URLSearchParams(queryString);
params.forEach((value, key) => {
query[key] = value;
});
}
// Find matching route
const route = this.findRoute(path);
if (route) {
const params = this.extractParams(path, route.path);
route.handler(params, query);
} else if (this.notFoundHandler) {
this.notFoundHandler();
}
}
// Find matching route
private findRoute(path: string): Route | null {
for (const route of this.routes) {
if (this.matchRoute(path, route.path)) {
return route;
}
}
return null;
}
// Check if path matches route pattern
private matchRoute(path: string, pattern: string): boolean {
const regexPattern = pattern
.replace(/:\\w+/g, '([^/]+)')
.replace(/\\*/g, '.*');
const regex = new RegExp(`^${regexPattern}$`);
return regex.test(path);
}
// Extract params from path
private extractParams(path: string, pattern: string): Record<string, string> {
const params: Record<string, string> = {};
const patternParts = pattern.split('/');
const pathParts = path.split('/');
for (let i = 0; i < patternParts.length; i++) {
const part = patternParts[i];
if (part.startsWith(':')) {
const paramName = part.substring(1);
params[paramName] = pathParts[i] || '';
}
}
return params;
}
// Replace params in path
private replaceParams(path: string, params: Record<string, string>): string {
let result = path;
for (const [key, value] of Object.entries(params)) {
result = result.replace(`:${key}`, value);
}
return result;
}
// Initialize hash router
initialize(): void {
window.addEventListener('hashchange', () => {
this.handleHashChange();
});
// Handle initial hash
this.handleHashChange();
}
}
// 4. Query Params Manager
class QueryParamsManager {
// Get query param
get(param: string): string | null {
const params = new URLSearchParams(window.location.search);
return params.get(param);
}
// Get all params
getAll(): Record<string, string> {
const params = new URLSearchParams(window.location.search);
const result: Record<string, string> = {};
params.forEach((value, key) => {
result[key] = value;
});
return result;
}
// Set query param
set(param: string, value: string): void {
const params = new URLSearchParams(window.location.search);
params.set(param, value);
this.update(params.toString());
}
// Delete query param
delete(param: string): void {
const params = new URLSearchParams(window.location.search);
params.delete(param);
this.update(params.toString());
}
// Clear all params
clear(): void {
this.update('');
}
// Update URL
private update(queryString: string): void {
const url = new URL(window.location.href);
url.search = queryString;
window.history.replaceState({}, '', url.toString());
}
// Watch for changes
watch(callback: (params: Record<string, string>) => void): () => void {
const handler = () => {
callback(this.getAll());
};
window.addEventListener('popstate', handler);
// Return cleanup function
return () => {
window.removeEventListener('popstate', handler);
};
}
}
// 5. Route Guard
class RouteGuard {
private guards: Map<string, () => boolean | Promise<boolean>> = new Map();
// Add guard for route
addGuard(route: string, guard: () => boolean | Promise<boolean>): void {
this.guards.set(route, guard);
}
// Check if route is allowed
async canNavigate(route: string): Promise<boolean> {
const guard = this.guards.get(route);
if (guard) {
return await guard();
}
return true;
}
// Add authentication guard
addAuthGuard(route: string, isAuthenticated: () => boolean): void {
this.addGuard(route, isAuthenticated);
}
// Add permission guard
addPermissionGuard(route: string, hasPermission: () => boolean | Promise<boolean>): void {
this.addGuard(route, hasPermission);
}
}
// 6. Navigation Manager
class NavigationManager {
private router: Router;
private history: string[] = [];
private currentIndex: number = -1;
constructor(router: Router) {
this.router = router;
}
// Navigate with history tracking
navigate(path: string, params: Record<string, string> = {}): void {
// Remove forward history if we're not at the end
if (this.currentIndex < this.history.length - 1) {
this.history = this.history.slice(0, this.currentIndex + 1);
}
// Add to history
this.history.push(path);
this.currentIndex++;
// Navigate
this.router.navigate(path, params);
}
// Go back in custom history
back(): void {
if (this.currentIndex > 0) {
this.currentIndex--;
const path = this.history[this.currentIndex];
window.history.back();
}
}
// Go forward in custom history
forward(): void {
if (this.currentIndex < this.history.length - 1) {
this.currentIndex++;
const path = this.history[this.currentIndex];
window.history.forward();
}
}
// Can go back
canGoBack(): boolean {
return this.currentIndex > 0;
}
// Can go forward
canGoForward(): boolean {
return this.currentIndex < this.history.length - 1;
}
// Get current position
getCurrentPosition(): number {
return this.currentIndex;
}
// Get history length
getHistoryLength(): number {
return this.history.length;
}
}
// 7. Route Transition Manager
class RouteTransitionManager {
private transitions: Map<string, (from: string, to: string) => void> = new Map();
// Add transition
addTransition(from: string, to: string, handler: () => void): void {
const key = this.getKey(from, to);
this.transitions.set(key, handler);
}
// Execute transition
execute(from: string, to: string): void {
const key = this.getKey(from, to);
const handler = this.transitions.get(key);
if (handler) {
handler(from, to);
}
}
// Add global transition
addGlobalTransition(handler: (from: string, to: string) => void): void {
this.transitions.set('*', handler);
}
// Generate transition key
private getKey(from: string, to: string): string {
return `${from}>${to}`;
}
}
// Usage Examples
async function demonstrateRouting() {
console.log('=== Web TypeScript Routing Examples ===\n');
// 1. Basic router
console.log('--- 1. Basic Router ---');
const router = new Router();
router.addRoute('/', (params, query) => {
console.log('Home page');
});
router.addRoute('/about', (params, query) => {
console.log('About page');
});
router.addRoute('/users/:id', (params, query) => {
console.log(`User page: ${params.id}`);
});
router.addRoute('/posts/:postId/comments/:commentId', (params, query) => {
console.log(`Comment: ${params.commentId} on post ${params.postId}`);
});
// 2. Navigation
console.log('\n--- 2. Navigation ---');
router.navigate('/');
await new Promise(resolve => setTimeout(resolve, 100));
router.navigate('/about');
await new Promise(resolve => setTimeout(resolve, 100));
router.navigate('/users/123');
await new Promise(resolve => setTimeout(resolve, 100));
// 3. Query params
console.log('\n--- 3. Query Params ---');
router.navigate('/search?query=typescript&page=1');
await new Promise(resolve => setTimeout(resolve, 100));
// 4. Hash router
console.log('\n--- 4. Hash Router ---');
const hashRouter = new HashRouter();
hashRouter.addRoute('/', (params, query) => {
console.log('Hash home');
});
hashRouter.addRoute('profile/:userId', (params, query) => {
console.log(`Hash profile: ${params.userId}`);
});
hashRouter.navigate('profile/456');
await new Promise(resolve => setTimeout(resolve, 100));
// 5. Query params manager
console.log('\n--- 5. Query Params Manager ---');
const queryManager = new QueryParamsManager();
queryManager.set('tab', 'profile');
queryManager.set('section', 'details');
const allParams = queryManager.getAll();
console.log('All params:', allParams);
// 6. Route guard
console.log('\n--- 6. Route Guard ---');
const guard = new RouteGuard();
guard.addAuthGuard('/admin', () => {
const isAuthenticated = false; // Simulate
console.log(`Auth check: ${isAuthenticated}`);
return isAuthenticated;
});
const canAccess = await guard.canNavigate('/admin');
console.log(`Can access /admin: ${canAccess}`);
// 7. Navigation manager
console.log('\n--- 7. Navigation Manager ---');
const navManager = new NavigationManager(router);
navManager.navigate('/page1');
await new Promise(resolve => setTimeout(resolve, 100));
navManager.navigate('/page2');
await new Promise(resolve => setTimeout(resolve, 100));
console.log(`Can go back: ${navManager.canGoBack()}`);
console.log(`History length: ${navManager.getHistoryLength()}`);
console.log('\n=== All Routing Examples Completed ===');
}
// Export functions
export { Router, HashRouter, QueryParamsManager, RouteGuard, NavigationManager, RouteTransitionManager };
export { demonstrateRouting };
export type { Route };
💻 Middleware typescript
🟡 intermediate
⭐⭐⭐⭐
Implementar cadeia de middleware solicitação/resposta para processar e modificar dados
⏱️ 30 min
🏷️ typescript, web, web features
Prerequisites:
Intermediate TypeScript, Promise chains, Async/await
💻 Arquivos Estáticos typescript
🟡 intermediate
⭐⭐⭐
Servir arquivos estáticos com cache, compactação e detecção de tipo MIME
⏱️ 25 min
🏷️ typescript, web, web features
Prerequisites:
Intermediate TypeScript, Fetch API, Blob
// Web TypeScript Static File Serving Examples
// Serving static files with various strategies
// 1. MIME Type Detector
class MIMETypeDetector {
private static mimeTypes: Record<string, string> = {
'.html': 'text/html',
'.htm': 'text/html',
'.css': 'text/css',
'.js': 'text/javascript',
'.json': 'application/json',
'.xml': 'application/xml',
'.txt': 'text/plain',
'.pdf': 'application/pdf',
'.zip': 'application/zip',
'.png': 'image/png',
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg',
'.gif': 'image/gif',
'.svg': 'image/svg+xml',
'.ico': 'image/x-icon',
'.woff': 'font/woff',
'.woff2': 'font/woff2',
'.ttf': 'font/ttf',
'.eot': 'application/vnd.ms-fontobject',
'.mp3': 'audio/mpeg',
'.mp4': 'video/mp4',
'.webm': 'video/webm',
'.ogg': 'video/ogg'
};
// Get MIME type by extension
static getByExtension(filename: string): string {
const ext = filename.substring(filename.lastIndexOf('.')).toLowerCase();
if (ext && this.mimeTypes[ext]) {
return this.mimeTypes[ext];
}
return 'application/octet-stream';
}
// Get MIME type by file signature (magic bytes)
static async getBySignature(file: Blob): Promise<string> {
const header = await this.readFileHeader(file);
// Check common signatures
if (this.startsWith(header, [0x89, 0x50, 0x4E, 0x47])) return 'image/png';
if (this.startsWith(header, [0xFF, 0xD8, 0xFF])) return 'image/jpeg';
if (this.startsWith(header, [0x47, 0x49, 0x46, 0x38])) return 'image/gif';
if (this.startsWith(header, [0x50, 0x4B, 0x03, 0x04])) return 'application/zip';
if (this.startsWith(header, [0x25, 0x50, 0x44, 0x46])) return 'application/pdf';
if (this.startsWith(header, [0x47, 0x49, 0x46, 0x38, 0x39, 0x61])) return 'image/gif';
return 'application/octet-stream';
}
// Read file header
private static async readFileHeader(file: Blob, bytes: number = 8): Promise<Uint8Array> {
const slice = file.slice(0, bytes);
const arrayBuffer = await slice.arrayBuffer();
return new Uint8Array(arrayBuffer);
}
// Check if header starts with bytes
private static startsWith(header: Uint8Array, bytes: number[]): boolean {
if (header.length < bytes.length) return false;
for (let i = 0; i < bytes.length; i++) {
if (header[i] !== bytes[i]) return false;
}
return true;
}
}
// 2. Static File Server
class StaticFileServer {
private baseUrl: string;
private cache: Map<string, { data: any; mime: string; timestamp: number }> = new Map();
private cacheTimeout: number = 60000; // 1 minute
constructor(baseUrl: string = '/static') {
this.baseUrl = baseUrl;
}
// Serve file
async serve(filePath: string): Promise<{
data: any;
mime: string;
status: number;
}> {
// Check cache
const cached = this.cache.get(filePath);
if (cached && Date.now() - cached.timestamp < this.cacheTimeout) {
return {
data: cached.data,
mime: cached.mime,
status: 200
};
}
// Fetch file
const url = `${this.baseUrl}${filePath}`;
try {
const response = await fetch(url);
if (!response.ok) {
return {
data: null,
mime: 'text/plain',
status: response.status
};
}
const mime = response.headers.get('Content-Type') ||
MIMETypeDetector.getByExtension(filePath);
let data: any;
const contentType = mime.split(';')[0];
if (contentType.includes('application/json')) {
data = await response.json();
} else if (contentType.includes('text/')) {
data = await response.text();
} else {
data = await response.blob();
}
// Cache response
this.cache.set(filePath, {
data,
mime,
timestamp: Date.now()
});
return { data, mime, status: 200 };
} catch (error) {
return {
data: null,
mime: 'text/plain',
status: 500
};
}
}
// Serve with fallback
async serveWithFallback(filePath: string, fallbackPath: string): Promise<{
data: any;
mime: string;
status: number;
}> {
const result = await this.serve(filePath);
if (result.status === 404) {
return this.serve(fallbackPath);
}
return result;
}
// Clear cache
clearCache(): void {
this.cache.clear();
}
// Clear specific cache entry
clearCacheEntry(filePath: string): void {
this.cache.delete(filePath);
}
// Get cache size
getCacheSize(): number {
return this.cache.size;
}
}
// 3. File Cache Manager
class FileCacheManager {
private cache: Map<string, {
content: any;
mimeType: string;
etag: string;
lastModified: string;
}> = new Map();
// Add to cache
set(filePath: string, content: any, mimeType: string, etag?: string, lastModified?: string): void {
this.cache.set(filePath, {
content,
mimeType,
etag: etag || this.generateETag(content),
lastModified: lastModified || new Date().toUTCString()
});
}
// Get from cache
get(filePath: string): {
content: any;
mimeType: string;
etag: string;
lastModified: string;
} | null {
return this.cache.get(filePath) || null;
}
// Check if file is cached
has(filePath: string): boolean {
return this.cache.has(filePath);
}
// Remove from cache
remove(filePath: string): void {
this.cache.delete(filePath);
}
// Clear all cache
clear(): void {
this.cache.clear();
}
// Get cache stats
getStats(): {
size: number;
entries: number;
keys: string[];
} {
return {
size: this.cache.size,
entries: this.cache.size,
keys: Array.from(this.cache.keys())
};
}
// Generate ETag
private generateETag(content: any): string {
const str = typeof content === 'string' ? content : JSON.stringify(content);
let hash = 0;
for (let i = 0; i < str.length; i++) {
const char = str.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash;
}
return `"${hash.toString(16)}"`;
}
}
// 4. Asset Preloader
class AssetPreloader {
private loadedAssets: Set<string> = new Set();
private failedAssets: Set<string> = new Set();
// Preload single asset
async preload(url: string): Promise<{
success: boolean;
error?: Error;
}> {
if (this.loadedAssets.has(url)) {
return { success: true };
}
if (this.failedAssets.has(url)) {
return { success: true, error: new Error('Previously failed to load') };
}
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
this.loadedAssets.add(url);
return { success: true };
} catch (error) {
this.failedAssets.add(url);
return { success: false, error: error as Error };
}
}
// Preload multiple assets
async preloadMultiple(urls: string[]): Promise<{
successful: string[];
failed: Array<{ url: string; error: Error }>;
}> {
const results = await Promise.allSettled(
urls.map(url => this.preload(url))
);
const successful: string[] = [];
const failed: Array<{ url: string; error: Error }> = [];
results.forEach((result, index) => {
if (result.status === 'fulfilled' && result.value.success) {
successful.push(urls[index]);
} else {
const error = result.status === 'rejected'
? result.reason
: (result.value as any).error;
failed.push({ url: urls[index], error });
}
});
return { successful, failed };
}
// Preload image
preloadImage(url: string): Promise<HTMLImageElement> {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => {
this.loadedAssets.add(url);
resolve(img);
};
img.onerror = () => {
this.failedAssets.add(url);
reject(new Error('Failed to load image'));
};
img.src = url;
});
}
// Preload images
async preloadImages(urls: string[]): Promise<HTMLImageElement[]> {
const results = await Promise.allSettled(
urls.map(url => this.preloadImage(url))
);
return results
.filter((result): result is PromiseFulfilledResult<HTMLImageElement> =>
result.status === 'fulfilled'
)
.map(result => result.value);
}
// Get loaded assets
getLoadedAssets(): string[] {
return Array.from(this.loadedAssets);
}
// Get failed assets
getFailedAssets(): string[] {
return Array.from(this.failedAssets);
}
// Clear tracking
clear(): void {
this.loadedAssets.clear();
this.failedAssets.clear();
}
}
// 5. Compression Handler
class CompressionHandler {
// Check if compression is supported
static isSupported(): boolean {
return 'CompressionStream' in window;
}
// Compress data (if supported)
static async compress(data: string, format: 'gzip' | 'deflate' = 'gzip'): Promise<Uint8Array> {
if (!this.isSupported()) {
throw new Error('Compression not supported');
}
const stream = new CompressionStream(format);
const writer = stream.writable.getWriter();
const encoder = new TextEncoder();
await writer.write(encoder.encode(data));
await writer.close();
const compressed = new ReadableStream({
start(controller) {
// Would need to implement proper stream reading
controller.close();
}
});
// This is a simplified version
return encoder.encode(data);
}
// Get best compression format
static getBestCompression(acceptEncoding: string): 'gzip' | 'deflate' | 'none' {
if (acceptEncoding.includes('br')) return 'gzip';
if (acceptEncoding.includes('gzip')) return 'gzip';
if (acceptEncoding.includes('deflate')) return 'deflate';
return 'none';
}
}
// 6. CDN Manager
class CDNManager {
private cdnUrls: string[] = [];
private currentCdnIndex: number = 0;
constructor(cdnUrls: string[]) {
this.cdnUrls = cdnUrls;
}
// Get CDN URL for asset
getCdnUrl(assetPath: string): string {
const cdnUrl = this.cdnUrls[this.currentCdnIndex];
return `${cdnUrl}${assetPath}`;
}
// Rotate CDN
rotateCdn(): void {
this.currentCdnIndex = (this.currentCdnIndex + 1) % this.cdnUrls.length;
}
// Get all CDN URLs for asset
getAllCdnUrls(assetPath: string): string[] {
return this.cdnUrls.map(cdn => `${cdn}${assetPath}`);
}
// Try each CDN until one succeeds
async tryAllCdns(assetPath: string): Promise<{
success: boolean;
cdnUrl?: string;
data?: any;
}> {
const urls = this.getAllCdnUrls(assetPath);
for (const url of urls) {
try {
const response = await fetch(url);
if (response.ok) {
const data = await response.blob();
return { success: true, cdnUrl: url, data };
}
} catch (error) {
console.warn(`CDN failed: ${url}`, error);
}
}
return { success: false };
}
}
// 7. Asset Bundle Manager
class AssetBundleManager {
private bundles: Map<string, string[]> = new Map();
// Register bundle
registerBundle(name: string, assets: string[]): void {
this.bundles.set(name, assets);
}
// Get bundle assets
getBundle(name: string): string[] | null {
return this.bundles.get(name) || null;
}
// Preload bundle
async preloadBundle(name: string, preloader: AssetPreloader): Promise<{
successful: string[];
failed: Array<{ url: string; error: Error }>;
}> {
const assets = this.getBundle(name);
if (!assets) {
return { successful: [], failed: [] };
}
return preloader.preloadMultiple(assets);
}
// Get bundle URL (for script/link tags)
getBundleHtml(name: string, type: 'script' | 'style'): string {
const assets = this.getBundle(name);
if (!assets) {
return '';
}
return assets.map(url => {
if (type === 'script') {
return `<script src="${url}"></script>`;
} else {
return `<link rel="stylesheet" href="${url}">`;
}
}).join('\n');
}
}
// Usage Examples
async function demonstrateStaticFiles() {
console.log('=== Web TypeScript Static File Serving Examples ===\n');
// 1. MIME type detection
console.log('--- 1. MIME Type Detection ---');
console.log('HTML:', MIMETypeDetector.getByExtension('index.html'));
console.log('JavaScript:', MIMETypeDetector.getByExtension('app.js'));
console.log('PNG:', MIMETypeDetector.getByExtension('image.png'));
// 2. Static file server
console.log('\n--- 2. Static File Server ---');
const server = new StaticFileServer('/assets');
// Note: These would make actual HTTP requests in a real environment
console.log('Would serve:', server.baseUrl + '/styles/main.css');
console.log('Would serve:', server.baseUrl + '/js/app.js');
// 3. File cache manager
console.log('\n--- 3. File Cache Manager ---');
const cacheManager = new FileCacheManager();
cacheManager.set('/index.html', '<html>...</html>', 'text/html', '"abc123"');
cacheManager.set('/app.js', 'console.log("Hello");', 'text/javascript');
console.log('Cache stats:', cacheManager.getStats());
const cached = cacheManager.get('/index.html');
console.log('Cached file:', cached?.mimeType);
// 4. Asset preloader
console.log('\n--- 4. Asset Preloader ---');
const preloader = new AssetPreloader();
// Note: These would be real URLs in production
const preloadResults = await preloader.preloadMultiple([
'/assets/image1.png',
'/assets/image2.png',
'/assets/image3.png'
]);
console.log('Preloaded:', preloadResults.successful);
console.log('Failed:', preloadResults.failed);
// 5. CDN manager
console.log('\n--- 5. CDN Manager ---');
const cdnManager = new CDNManager([
'https://cdn1.example.com',
'https://cdn2.example.com',
'https://cdn3.example.com'
]);
console.log('CDN URL:', cdnManager.getCdnUrl('/assets/app.js'));
cdnManager.rotateCdn();
console.log('Rotated CDN URL:', cdnManager.getCdnUrl('/assets/app.js'));
// 6. Asset bundle manager
console.log('\n--- 6. Asset Bundle Manager ---');
const bundleManager = new AssetBundleManager();
bundleManager.registerBundle('vendor', [
'/assets/js/vendor/react.js',
'/assets/js/vendor/lodash.js'
]);
bundleManager.registerBundle('app', [
'/assets/js/app.js',
'/assets/js/utils.js'
]);
const bundle = bundleManager.getBundle('vendor');
console.log('Vendor bundle:', bundle);
console.log('\n=== All Static File Serving Examples Completed ===');
}
// Export functions
export { MIMETypeDetector, StaticFileServer, FileCacheManager, AssetPreloader, CompressionHandler, CDNManager, AssetBundleManager };
export { demonstrateStaticFiles };