@twardoch/namzy 1.0.21 → 1.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { applyRotations, buildName, mulberry32 } from "./mangle.js";
1
+ import { applyRotation, buildName, mulberry32 } from "./mangle.js";
2
2
  export interface NamzyOptions {
3
3
  seed?: number;
4
4
  }
@@ -7,4 +7,4 @@ export declare function generate(opts?: NamzyOptions): string;
7
7
  /** Generate `count` names. Distinct seeds derived from the base seed. */
8
8
  export declare function generateMany(count: number, opts?: NamzyOptions): string[];
9
9
  export { STEMS, ROTATIONS } from "./wordlist.js";
10
- export { applyRotations, buildName, mulberry32 };
10
+ export { applyRotation, buildName, mulberry32 };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // this_file: src/index.ts
2
- import { applyRotations, buildName, mulberry32 } from "./mangle.js";
2
+ import { applyRotation, buildName, mulberry32 } from "./mangle.js";
3
3
  /** Generate one namzy name. Default seed is the current timestamp. */
4
4
  export function generate(opts) {
5
5
  const seed = opts?.seed ?? Date.now();
@@ -15,4 +15,4 @@ export function generateMany(count, opts) {
15
15
  return out;
16
16
  }
17
17
  export { STEMS, ROTATIONS } from "./wordlist.js";
18
- export { applyRotations, buildName, mulberry32 };
18
+ export { applyRotation, buildName, mulberry32 };
package/dist/mangle.d.ts CHANGED
@@ -1,6 +1,5 @@
1
- /** Seeded mulberry32 RNG — yields [0,1) floats. */
2
1
  export declare function mulberry32(seed: number): () => number;
3
- /** Apply 1 or 2 rotations on randomly selected positions of the compound. */
4
- export declare function applyRotations(compound: string, rng: () => number): string;
5
- /** Build one name: any two stems, concatenated, lightly rotated, capitalized. */
2
+ /** Apply one rotation at a randomly chosen matching position. */
3
+ export declare function applyRotation(s: string, rng: () => number): string;
4
+ /** Build one name with junction validation + one rotation. */
6
5
  export declare function buildName(rng: () => number): string;
package/dist/mangle.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // this_file: src/mangle.ts
2
- import { ROTATIONS, STEMS } from "./wordlist.js";
3
- /** Seeded mulberry32 RNG — yields [0,1) floats. */
2
+ import { BAD_SEAMS, ROTATIONS, STEMS } from "./wordlist.js";
3
+ const MAX_LEN = 12;
4
+ const MAX_TRIES = 8;
4
5
  export function mulberry32(seed) {
5
6
  let s = seed >>> 0;
6
7
  return () => {
@@ -13,33 +14,63 @@ export function mulberry32(seed) {
13
14
  function pick(arr, rng) {
14
15
  return arr[Math.floor(rng() * arr.length)];
15
16
  }
16
- const ROT_MAP = new Map(ROTATIONS);
17
- function rotateAt(s, pos) {
18
- const ch = s[pos];
19
- const lower = ch.toLowerCase();
20
- const repl = ROT_MAP.get(lower);
21
- if (repl === undefined)
22
- return s;
23
- const out = ch === lower ? repl : repl.toUpperCase();
24
- return s.slice(0, pos) + out + s.slice(pos + 1);
17
+ function hasTripleLetter(s) {
18
+ for (let i = 2; i < s.length; i++) {
19
+ if (s[i] === s[i - 1] && s[i] === s[i - 2])
20
+ return true;
21
+ }
22
+ return false;
23
+ }
24
+ function junctionUgly(compound, junction) {
25
+ // Inspect the 4-char window centered on the junction.
26
+ const start = Math.max(0, junction - 2);
27
+ const end = Math.min(compound.length, junction + 2);
28
+ const win = compound.slice(start, end);
29
+ for (const seam of BAD_SEAMS) {
30
+ if (win.includes(seam))
31
+ return true;
32
+ }
33
+ return false;
25
34
  }
26
- /** Apply 1 or 2 rotations on randomly selected positions of the compound. */
27
- export function applyRotations(compound, rng) {
28
- if (compound.length === 0)
29
- return compound;
30
- const passes = rng() < 0.5 ? 1 : 2;
31
- let out = compound;
32
- for (let i = 0; i < passes; i++) {
33
- out = rotateAt(out, Math.floor(rng() * out.length));
35
+ /** Apply one rotation at a randomly chosen matching position. */
36
+ export function applyRotation(s, rng) {
37
+ const matches = [];
38
+ for (let i = 0; i < s.length; i++) {
39
+ for (const [src, dst] of ROTATIONS) {
40
+ if (s.slice(i, i + src.length) === src) {
41
+ matches.push({ i, src, dst });
42
+ }
43
+ }
34
44
  }
35
- return out;
45
+ if (matches.length === 0)
46
+ return s;
47
+ const m = matches[Math.floor(rng() * matches.length)];
48
+ return s.slice(0, m.i) + m.dst + s.slice(m.i + m.src.length);
36
49
  }
37
50
  function capitalize(s) {
38
51
  return s.length === 0 ? s : s[0].toUpperCase() + s.slice(1);
39
52
  }
40
- /** Build one name: any two stems, concatenated, lightly rotated, capitalized. */
53
+ /** Build one name with junction validation + one rotation. */
41
54
  export function buildName(rng) {
42
- const a = pick(STEMS, rng);
43
- const b = pick(STEMS, rng);
44
- return capitalize(applyRotations(a + b, rng));
55
+ let best = "";
56
+ for (let attempt = 0; attempt < MAX_TRIES; attempt++) {
57
+ const a = pick(STEMS, rng);
58
+ const b = pick(STEMS, rng);
59
+ const compound = a + b;
60
+ if (compound.length > MAX_LEN) {
61
+ best = best || compound;
62
+ continue;
63
+ }
64
+ if (hasTripleLetter(compound)) {
65
+ best = best || compound;
66
+ continue;
67
+ }
68
+ if (junctionUgly(compound, a.length)) {
69
+ best = best || compound;
70
+ continue;
71
+ }
72
+ return capitalize(applyRotation(compound, rng));
73
+ }
74
+ // All attempts had some flaw; rotate and ship the first candidate anyway.
75
+ return capitalize(applyRotation(best, rng));
45
76
  }
package/dist/web.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { generate, generateMany, applyRotations, buildName, mulberry32, STEMS, ROTATIONS } from "./index.js";
1
+ export { generate, generateMany, applyRotation, buildName, mulberry32, STEMS, ROTATIONS } from "./index.js";
2
2
  export type { NamzyOptions } from "./index.js";
package/dist/web.js CHANGED
@@ -1,3 +1,3 @@
1
1
  // this_file: src/web.ts
2
2
  // Browser entry point — exposes namzy.generate() on window.namzy.
3
- export { generate, generateMany, applyRotations, buildName, mulberry32, STEMS, ROTATIONS } from "./index.js";
3
+ export { generate, generateMany, applyRotation, buildName, mulberry32, STEMS, ROTATIONS } from "./index.js";
@@ -1,2 +1,3 @@
1
1
  export declare const STEMS: readonly string[];
2
2
  export declare const ROTATIONS: readonly (readonly [string, string])[];
3
+ export declare const BAD_SEAMS: readonly string[];