| 1 | const ALPHABET = "0123456789abcdefghjkmnpqrstvwxyz"; |
| 2 | |
| 3 | export type IdPrefix = "usr" | "ses" | "tok" | "key" | "rep" | "int" | "att" | "evt"; |
| 4 | |
| 5 | /** |
| 6 | * A prefixed, time-sortable id such as `att_01jb2…`: 48 bits of millisecond |
| 7 | * timestamp then 80 random bits, in lowercase Crockford base32. Sorting ids |
| 8 | * as strings sorts them by creation time. |
| 9 | */ |
| 10 | export function newId(prefix: IdPrefix, now: number = Date.now()): string { |
| 11 | let time = ""; |
| 12 | for (let i = 0, t = now; i < 10; i++, t = Math.floor(t / 32)) { |
| 13 | time = ALPHABET[t % 32] + time; |
| 14 | } |
| 15 | let random = ""; |
| 16 | for (const byte of crypto.getRandomValues(new Uint8Array(16))) { |
| 17 | random += ALPHABET[byte % 32]; |
| 18 | } |
| 19 | return `${prefix}_${time}${random}`; |
| 20 | } |