@dicebear/core 10.0.0-rc.5 → 10.0.1

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/lib/Options.d.ts CHANGED
@@ -26,12 +26,11 @@ export declare class Options<D = unknown> {
26
26
  translateX(): Range | undefined;
27
27
  translateY(): Range | undefined;
28
28
  /**
29
- * Returns the user-set variant constraint for `name`:
30
- * - `undefined` when the user did not set `${name}Variant`,
31
- * - `string[]` when the user gave a string or string list (each weighted 1),
32
- * - `Record<string, number>` when the user gave a weighted map.
29
+ * Returns the user-set variant constraint for `name` as a weighted map, or
30
+ * `undefined` when `${name}Variant` is unset. A bare string or string list
31
+ * is normalized to a map with each entry weighted `1`.
33
32
  */
34
- componentVariant(name: string): readonly string[] | Readonly<Record<string, number>> | undefined;
33
+ componentVariant(name: string): Readonly<Record<string, number>> | undefined;
35
34
  componentProbability(name: string): number | undefined;
36
35
  /**
37
36
  * Asymmetric on purpose: returns `undefined` (rather than `[]`) when
package/lib/Options.js CHANGED
@@ -65,18 +65,20 @@ export class Options {
65
65
  return __classPrivateFieldGet(this, _Options_instances, "m", _Options_toRange).call(this, __classPrivateFieldGet(this, _Options_data, "f").translateY);
66
66
  }
67
67
  /**
68
- * Returns the user-set variant constraint for `name`:
69
- * - `undefined` when the user did not set `${name}Variant`,
70
- * - `string[]` when the user gave a string or string list (each weighted 1),
71
- * - `Record<string, number>` when the user gave a weighted map.
68
+ * Returns the user-set variant constraint for `name` as a weighted map, or
69
+ * `undefined` when `${name}Variant` is unset. A bare string or string list
70
+ * is normalized to a map with each entry weighted `1`.
72
71
  */
73
72
  componentVariant(name) {
74
73
  const raw = __classPrivateFieldGet(this, _Options_instances, "m", _Options_dynamic).call(this, `${name}Variant`);
75
74
  if (raw === undefined) {
76
75
  return undefined;
77
76
  }
78
- if (typeof raw === 'string' || Array.isArray(raw)) {
79
- return __classPrivateFieldGet(this, _Options_instances, "m", _Options_asArray).call(this, raw);
77
+ if (typeof raw === 'string') {
78
+ return { [raw]: 1 };
79
+ }
80
+ if (Array.isArray(raw)) {
81
+ return Object.fromEntries(raw.map((v) => [v, 1]));
80
82
  }
81
83
  return raw;
82
84
  }
@@ -21,6 +21,7 @@ interface EnumField {
21
21
  interface ColorField {
22
22
  readonly type: 'color';
23
23
  readonly list?: true;
24
+ readonly contrastTo?: string;
24
25
  }
25
26
  interface RangeField {
26
27
  readonly type: 'range';
@@ -63,7 +63,12 @@ _a = OptionsDescriptor, _OptionsDescriptor_descriptor = new WeakMap(), _OptionsD
63
63
  result[`${name}Probability`] = { type: 'number', min: 0, max: 100 };
64
64
  }
65
65
  for (const name of [...__classPrivateFieldGet(this, _OptionsDescriptor_style, "f").colors().keys(), 'background']) {
66
- result[`${name}Color`] = { type: 'color', list: true };
66
+ const contrastTo = __classPrivateFieldGet(this, _OptionsDescriptor_style, "f").colors().get(name)?.contrastTo();
67
+ result[`${name}Color`] = {
68
+ type: 'color',
69
+ list: true,
70
+ ...(contrastTo ? { contrastTo } : {}),
71
+ };
67
72
  result[`${name}ColorFill`] = {
68
73
  type: 'enum',
69
74
  values: ['solid', 'linear', 'radial'],
package/lib/Prng.d.ts CHANGED
@@ -17,13 +17,11 @@ export declare class Prng {
17
17
  */
18
18
  pick<T>(key: string, items: readonly T[]): T | undefined;
19
19
  /**
20
- * Picks an item from `entries` proportional to its weight. Duplicate items
21
- * (by string representation) are collapsed before picking only the
22
- * first occurrence's weight is kept. When all weights are zero, falls
23
- * back to an unweighted {@link pick}. Returns `undefined` for an empty
24
- * list.
20
+ * Picks a key from `weights` proportional to its weight. When all weights
21
+ * are zero, falls back to an unweighted {@link pick}. Returns `undefined`
22
+ * for an empty map.
25
23
  */
26
- weightedPick<T>(key: string, entries: readonly (readonly [T, number])[]): T | undefined;
24
+ weightedPick(key: string, weights: Readonly<Record<string, number>>): string | undefined;
27
25
  /**
28
26
  * Returns `true` with the given probability (0–100, default 50).
29
27
  */
package/lib/Prng.js CHANGED
@@ -47,34 +47,32 @@ export class Prng {
47
47
  return sorted[index];
48
48
  }
49
49
  /**
50
- * Picks an item from `entries` proportional to its weight. Duplicate items
51
- * (by string representation) are collapsed before picking only the
52
- * first occurrence's weight is kept. When all weights are zero, falls
53
- * back to an unweighted {@link pick}. Returns `undefined` for an empty
54
- * list.
50
+ * Picks a key from `weights` proportional to its weight. When all weights
51
+ * are zero, falls back to an unweighted {@link pick}. Returns `undefined`
52
+ * for an empty map.
55
53
  */
56
- weightedPick(key, entries) {
57
- if (entries.length === 0) {
54
+ weightedPick(key, weights) {
55
+ const keys = Object.keys(weights);
56
+ if (keys.length === 0) {
58
57
  return undefined;
59
58
  }
60
- if (entries.length === 1) {
61
- return entries[0][0];
59
+ if (keys.length === 1) {
60
+ return keys[0];
62
61
  }
63
- const unique = __classPrivateFieldGet(this, _Prng_instances, "m", _Prng_uniqueByCodePoint).call(this, entries, (e) => String(e[0]));
64
- const sorted = unique.sort((a, b) => __classPrivateFieldGet(this, _Prng_instances, "m", _Prng_compareByCodePoint).call(this, a[0], b[0]));
65
- const totalWeight = sorted.reduce((sum, e) => sum + e[1], 0);
62
+ const sorted = keys.sort(__classPrivateFieldGet(this, _Prng_instances, "m", _Prng_compareByCodePoint));
63
+ const totalWeight = sorted.reduce((sum, k) => sum + weights[k], 0);
66
64
  if (totalWeight === 0) {
67
- return this.pick(key, sorted.map((e) => e[0]));
65
+ return this.pick(key, sorted);
68
66
  }
69
67
  const threshold = this.getValue(key) * totalWeight;
70
68
  let cumulative = 0;
71
- for (const [item, weight] of sorted) {
72
- cumulative += weight;
69
+ for (const k of sorted) {
70
+ cumulative += weights[k];
73
71
  if (threshold < cumulative) {
74
- return item;
72
+ return k;
75
73
  }
76
74
  }
77
- return sorted[sorted.length - 1][0];
75
+ return sorted[sorted.length - 1];
78
76
  }
79
77
  /**
80
78
  * Returns `true` with the given probability (0–100, default 50).
package/lib/Resolver.d.ts CHANGED
@@ -30,8 +30,9 @@ export declare class Resolver<D = unknown> {
30
30
  * as `${name}Variant` in the input data:
31
31
  *
32
32
  * - `undefined`: PRNG picks from all style variants using their weights.
33
- * - `string` or `string[]`: PRNG picks from the given subset (weight 1 each).
34
- * - `Record<string, number>`: PRNG picks using the provided weights.
33
+ * - otherwise: PRNG picks using the user-supplied weighted map (a bare
34
+ * string or string list is normalized to weight `1` each in
35
+ * {@link Options.componentVariant}).
35
36
  *
36
37
  * Only variants that exist in the style definition are considered.
37
38
  */
package/lib/Resolver.js CHANGED
@@ -78,8 +78,9 @@ export class Resolver {
78
78
  * as `${name}Variant` in the input data:
79
79
  *
80
80
  * - `undefined`: PRNG picks from all style variants using their weights.
81
- * - `string` or `string[]`: PRNG picks from the given subset (weight 1 each).
82
- * - `Record<string, number>`: PRNG picks using the provided weights.
81
+ * - otherwise: PRNG picks using the user-supplied weighted map (a bare
82
+ * string or string list is normalized to weight `1` each in
83
+ * {@link Options.componentVariant}).
83
84
  *
84
85
  * Only variants that exist in the style definition are considered.
85
86
  */
@@ -91,22 +92,20 @@ export class Resolver {
91
92
  }
92
93
  const raw = __classPrivateFieldGet(this, _Resolver_options, "f").componentVariant(component.sourceName());
93
94
  const variants = component.variants();
94
- let entries;
95
+ const weights = {};
95
96
  if (raw === undefined) {
96
- entries = Array.from(variants).map(([v, variant]) => [
97
- v,
98
- variant.weight(),
99
- ]);
100
- }
101
- else if (Array.isArray(raw)) {
102
- entries = raw
103
- .filter((v) => variants.has(v))
104
- .map((v) => [v, 1]);
97
+ for (const [v, variant] of variants) {
98
+ weights[v] = variant.weight();
99
+ }
105
100
  }
106
101
  else {
107
- entries = Object.entries(raw).filter(([v]) => variants.has(v));
102
+ for (const [v, w] of Object.entries(raw)) {
103
+ if (variants.has(v)) {
104
+ weights[v] = w;
105
+ }
106
+ }
108
107
  }
109
- return __classPrivateFieldGet(this, _Resolver_prng, "f").weightedPick(`${name}Variant`, entries);
108
+ return __classPrivateFieldGet(this, _Resolver_prng, "f").weightedPick(`${name}Variant`, weights);
110
109
  });
111
110
  }
112
111
  color(name) {
package/lib/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { Style, type StyleDefinition } from './Style.js';
2
2
  export { Avatar } from './Avatar.js';
3
+ export { Color } from './Utils/Color.js';
3
4
  export { OptionsDescriptor } from './OptionsDescriptor.js';
4
5
  export type { StyleOptions } from './StyleOptions.js';
package/lib/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export { Style } from './Style.js';
2
2
  export { Avatar } from './Avatar.js';
3
+ export { Color } from './Utils/Color.js';
3
4
  export { OptionsDescriptor } from './OptionsDescriptor.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dicebear/core",
3
- "version": "10.0.0-rc.5",
3
+ "version": "10.0.1",
4
4
  "description": "Unique avatars from dozens of styles — deterministic, customizable, vector-based.",
5
5
  "keywords": [
6
6
  "avatar",