LCOV - code coverage report
Current view: top level - dashql-app/src/session/scripts - script_name.ts Coverage Total Hit
Test: DashQL 915828b Lines: 100.0 % 35 35
Test Date: 2026-11-06 19:30:32

            Line data    Source code
       1              : /// Random two-word name generator for new scripts.
       2              : ///
       3              : /// Instead of naming every new script "script", we compose a memorable "<adjective>_<animal>" base
       4              : /// (e.g. "brave_otter") in the spirit of whimsical generated names. The two curated
       5              : /// word lists give ADJECTIVES.length * ANIMALS.length combinations, so collisions on a single page
       6              : /// are rare; when one does occur the caller's uniqueScriptBase still disambiguates with a "-2" suffix.
       7              : 
       8            1 : const ADJECTIVES: readonly string[] = [
       9            1 :     'amber', 'ancient', 'autumn', 'azure', 'bold', 'brave', 'breezy', 'bright',
      10            1 :     'brisk', 'calm', 'clever', 'cosmic', 'crimson', 'crisp', 'curious', 'daring',
      11            1 :     'dawn', 'deep', 'eager', 'electric', 'emerald', 'fancy', 'fearless', 'fierce',
      12            1 :     'fluffy', 'frosty', 'gentle', 'gilded', 'golden', 'happy', 'hidden', 'humble',
      13            1 :     'icy', 'indigo', 'jolly', 'keen', 'lively', 'lucid', 'lucky', 'mellow',
      14            1 :     'merry', 'mighty', 'misty', 'nimble', 'noble', 'patient', 'placid', 'polished',
      15            1 :     'proud', 'quiet', 'rapid', 'royal', 'rugged', 'rustic', 'scarlet', 'serene',
      16            1 :     'silent', 'silver', 'sleek', 'snowy', 'solar', 'spry', 'stellar', 'sturdy',
      17            1 :     'sunny', 'swift', 'tidy', 'tranquil', 'velvet', 'vivid', 'wandering', 'wise',
      18            1 :     'witty', 'zesty',
      19            1 : ];
      20              : 
      21            1 : const ANIMALS: readonly string[] = [
      22            1 :     'badger', 'bat', 'bear', 'beaver', 'bison', 'cheetah', 'cobra', 'condor',
      23            1 :     'cougar', 'coyote', 'crane', 'cricket', 'dingo', 'dolphin', 'eagle', 'falcon',
      24            1 :     'ferret', 'finch', 'fox', 'gazelle', 'gecko', 'gibbon', 'heron', 'ibex',
      25            1 :     'iguana', 'impala', 'jackal', 'jaguar', 'kestrel', 'koala', 'lemur', 'leopard',
      26            1 :     'lynx', 'magpie', 'mantis', 'marmot', 'marten', 'meerkat', 'mole', 'moose',
      27            1 :     'narwhal', 'newt', 'ocelot', 'orca', 'osprey', 'otter', 'owl', 'panda',
      28            1 :     'panther', 'pelican', 'penguin', 'puffin', 'puma', 'quail', 'rabbit', 'raccoon',
      29            1 :     'raven', 'salmon', 'seal', 'shark', 'sparrow', 'stoat', 'stork', 'tapir',
      30            1 :     'teal', 'tiger', 'toucan', 'turtle', 'viper', 'vole', 'walrus', 'weasel',
      31            1 :     'wolf', 'wombat',
      32            1 : ];
      33              : 
      34              : /// How many random combinations to try before giving up on finding a collision-free one. With a few
      35              : /// thousand combinations this practically never exhausts; the caller still de-duplicates afterwards.
      36            1 : const MAX_ATTEMPTS = 32;
      37              : 
      38            1 : function pick(list: readonly string[], rng: () => number): string {
      39            1 :     return list[Math.floor(rng() * list.length)];
      40            1 : }
      41              : 
      42              : /// Generate a random "<adjective>-<animal>" script base. If `taken` is given, retries a bounded number
      43              : /// of times to avoid names already present; on exhaustion it returns a name regardless (the caller's
      44              : /// uniqueScriptBase appends a numeric suffix to guarantee uniqueness). `rng` is injectable for tests.
      45            1 : export function randomScriptName(taken?: ReadonlySet<string>, rng: () => number = Math.random): string {
      46            1 :     let candidate = `${pick(ADJECTIVES, rng)}_${pick(ANIMALS, rng)}`;
      47            1 :     if (!taken) return candidate;
      48            1 :     for (let attempt = 0; taken.has(candidate) && attempt < MAX_ATTEMPTS; ++attempt) {
      49            1 :         candidate = `${pick(ADJECTIVES, rng)}_${pick(ANIMALS, rng)}`;
      50              :     }
      51            1 :     return candidate;
      52            1 : }
        

Generated by: LCOV version 2.0-1