UNPKG

@nitrogenbuilder/client-core

Version:

Nitrogen Builder Core Client

77 lines (69 loc) 2.14 kB
import type { BuilderModule } from '@nitrogenbuilder/types'; 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(): string { 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: number): string { 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: string): number { 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: BuilderModule[]): Set<string> { const ids = new Set<string>(); function walk(mods: BuilderModule[]) { 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: BuilderModule[], extraUsed?: Set<string> ): string { 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: string): boolean { return SHORT_ID_PATTERN.test(id); }