Files
hitstar/src/server-deno/infrastructure/TokenStoreService.ts

73 lines
1.6 KiB
TypeScript

import { encodeHex } from '@std/encoding/hex';
import { LRUCache } from 'lru-cache';
import type { AudioToken } from '../domain/types.ts';
import { TOKEN_CACHE_MAX_ITEMS, TOKEN_TTL_MS } from '../shared/constants.ts';
/**
* Token store service for managing short-lived audio streaming tokens
*/
export class TokenStoreService {
private readonly tokenCache: LRUCache<string, AudioToken>;
constructor(ttlMs: number = TOKEN_TTL_MS) {
this.tokenCache = new LRUCache<string, AudioToken>({
max: TOKEN_CACHE_MAX_ITEMS,
ttl: ttlMs,
ttlAutopurge: true,
allowStale: false,
updateAgeOnGet: false,
updateAgeOnHas: false,
});
}
/**
* Generate a random token
*/
private generateToken(): string {
const bytes = new Uint8Array(16);
crypto.getRandomValues(bytes);
return encodeHex(bytes);
}
/**
* Create and store a new token
*/
putToken(value: AudioToken, ttlMs?: number): string {
const token = this.generateToken();
const options = ttlMs ? { ttl: Math.max(1000, ttlMs) } : undefined;
this.tokenCache.set(token, value, options);
return token;
}
/**
* Retrieve token data
*/
getToken(token: string): AudioToken | undefined {
if (!token) return undefined;
return this.tokenCache.get(token);
}
/**
* Remove a token
*/
deleteToken(token: string): boolean {
return this.tokenCache.delete(token);
}
/**
* Clear all tokens
*/
clearAll(): void {
this.tokenCache.clear();
}
/**
* Get cache size
*/
getSize(): number {
return this.tokenCache.size;
}
}