UNPKG

@nitrogenbuilder/client-core

Version:

Nitrogen Builder Core Client

72 lines (71 loc) 2.24 kB
const ALPHA = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; const ALNUM = ALPHA + '0123456789'; // Random 4-char id. Only a FALLBACK now (before a siteId is assigned, or if the // server runs out of single-char site ids). Primary minting is namespaced and // collision-free (siteId + base62 counter) — see `nextNamespacedId` / the editor. export function generateShortId() { let id = ALPHA[Math.floor(Math.random() * ALPHA.length)]; for (let i = 0; i < 3; i++) { id += ALNUM[Math.floor(Math.random() * ALNUM.length)]; } return id; } // base62 codec for the per-client id counter (compact, letter-or-digit chars). const B62 = ALNUM; // a-zA-Z0-9 export function toBase62(n) { if (n <= 0) return B62[0]; // zero-digit, so it round-trips (fromBase62 → 0) let s = ''; while (n > 0) { s = B62[n % 62] + s; n = Math.floor(n / 62); } return s; } export function fromBase62(s) { let n = 0; for (const c of s) { const i = B62.indexOf(c); if (i < 0) return NaN; n = n * 62 + i; } return n; } export function collectIds(page) { const ids = new Set(); function walk(mods) { for (const mod of mods) { ids.add(mod.id); const children = mod.props?.children; if (Array.isArray(children)) { walk(children); } else if (children && typeof children === 'object') { for (const slot of Object.keys(children)) { if (Array.isArray(children[slot])) walk(children[slot]); } } } } walk(page); return ids; } export function generateUniqueShortId(page, extraUsed) { const used = collectIds(page); if (extraUsed) { for (const id of extraUsed) used.add(id); } for (let i = 0; i < 100; i++) { const id = generateShortId(); if (!used.has(id)) return id; } throw new Error('shortId: exhausted attempts generating unique id'); } export const SHORT_ID_PATTERN = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/; export function isValidId(id) { return SHORT_ID_PATTERN.test(id); }