/** * Generates a UUID v4. * Falls back to a manual implementation when crypto.randomUUID is unavailable * (HTTP non-secure contexts, older browsers). */ export function generateUUID(): string { if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') { return crypto.randomUUID() } // Fallback: RFC 4122 v4 UUID using crypto.getRandomValues if available if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') { const bytes = new Uint8Array(16) crypto.getRandomValues(bytes) bytes[6] = (bytes[6] & 0x0f) | 0x40 bytes[8] = (bytes[8] & 0x3f) | 0x80 return [...bytes] .map((b, i) => ([4, 6, 8, 10].includes(i) ? '-' : '') + b.toString(16).padStart(2, '0')) .join('') } // Last resort: Math.random based (not cryptographically secure) return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { const r = (Math.random() * 16) | 0 return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16) }) }