| 108 | // ─── Helpers ───────────────────────────────────────────────────── |
| 109 | |
| 110 | function newBoardId(): string { |
| 111 | const now = new Date(); |
| 112 | const y = now.getUTCFullYear().toString().padStart(4, "0"); |
| 113 | const mo = (now.getUTCMonth() + 1).toString().padStart(2, "0"); |
| 114 | const d = now.getUTCDate().toString().padStart(2, "0"); |
| 115 | const hh = now.getUTCHours().toString().padStart(2, "0"); |
| 116 | const mm = now.getUTCMinutes().toString().padStart(2, "0"); |
| 117 | const ss = now.getUTCSeconds().toString().padStart(2, "0"); |
| 118 | const rand = Math.random().toString(36).slice(2, 8).padEnd(6, "0"); |
| 119 | return `b-${y}${mo}${d}-${hh}${mm}${ss}-${rand}`; |
| 120 | } |
| 121 | |
| 122 | async function withBoardMutex<T>(id: string, fn: () => Promise<T>): Promise<T> { |
| 123 | const prev = boardMutex.get(id) || Promise.resolve(); |