Files
CodeNomad/packages/ui/src/lib/client-identity.ts

59 lines
1.6 KiB
TypeScript

const CLIENT_ID_STORAGE_KEY = "codenomad.client-id"
const CONNECTION_ID_STORAGE_KEY = "codenomad.connection-id"
let cachedClientId: string | null = null
let cachedConnectionId: string | null = null
export function getClientIdentity(): { clientId: string; connectionId: string } {
return {
clientId: getOrCreateClientId(),
connectionId: getOrCreateConnectionId(),
}
}
function getOrCreateClientId(): string {
if (cachedClientId) return cachedClientId
cachedClientId = getOrCreateStoredValue(CLIENT_ID_STORAGE_KEY, window.localStorage)
return cachedClientId
}
function getOrCreateConnectionId(): string {
if (cachedConnectionId) return cachedConnectionId
cachedConnectionId = getOrCreateStoredValue(CONNECTION_ID_STORAGE_KEY, window.sessionStorage)
return cachedConnectionId
}
function getOrCreateStoredValue(key: string, storage: Storage): string {
if (typeof window === "undefined") {
return generateUUID()
}
try {
const existing = storage.getItem(key)
if (existing && existing.trim()) {
return existing.trim()
}
} catch {
return generateUUID()
}
const next = generateUUID()
try {
storage.setItem(key, next)
} catch {
// Ignore storage failures and fall back to the in-memory value.
}
return next
}
function generateUUID(): string {
if (typeof crypto !== "undefined" && crypto.randomUUID) {
return crypto.randomUUID()
}
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (char) => {
const random = (Math.random() * 16) | 0
const value = char === "x" ? random : (random & 0x3) | 0x8
return value.toString(16)
})
}